ajaxter-chat 1.0.1 → 2.0.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.
Files changed (87) hide show
  1. package/README.md +96 -191
  2. package/dist/components/ChatScreen/index.d.ts +12 -0
  3. package/dist/components/ChatScreen/index.js +83 -0
  4. package/dist/components/ChatWidget.d.ts +0 -24
  5. package/dist/components/ChatWidget.js +129 -38
  6. package/dist/components/HomeScreen/index.d.ts +9 -0
  7. package/dist/components/HomeScreen/index.js +71 -0
  8. package/dist/components/MaintenanceView/index.d.ts +1 -1
  9. package/dist/components/MaintenanceView/index.js +15 -52
  10. package/dist/components/RecentChatsScreen/index.d.ts +16 -0
  11. package/dist/components/RecentChatsScreen/index.js +38 -0
  12. package/dist/components/Tabs/BottomTabs.d.ts +10 -0
  13. package/dist/components/Tabs/BottomTabs.js +29 -0
  14. package/dist/components/TicketScreen/index.d.ts +9 -0
  15. package/dist/components/TicketScreen/index.js +71 -0
  16. package/dist/components/UserListScreen/index.d.ts +13 -0
  17. package/dist/components/UserListScreen/index.js +64 -0
  18. package/dist/config/index.js +19 -74
  19. package/dist/hooks/useChat.d.ts +3 -7
  20. package/dist/hooks/useChat.js +8 -30
  21. package/dist/hooks/useUsers.d.ts +3 -10
  22. package/dist/hooks/useUsers.js +5 -11
  23. package/dist/index.d.ts +8 -7
  24. package/dist/index.js +7 -12
  25. package/dist/services/userService.d.ts +0 -5
  26. package/dist/services/userService.js +6 -13
  27. package/dist/src/components/ChatScreen/index.d.ts +12 -0
  28. package/dist/src/components/ChatScreen/index.js +83 -0
  29. package/dist/src/components/ChatWidget.d.ts +4 -0
  30. package/dist/src/components/ChatWidget.js +141 -0
  31. package/dist/src/components/HomeScreen/index.d.ts +9 -0
  32. package/dist/src/components/HomeScreen/index.js +71 -0
  33. package/dist/src/components/MaintenanceView/index.d.ts +7 -0
  34. package/dist/src/components/MaintenanceView/index.js +16 -0
  35. package/dist/src/components/RecentChatsScreen/index.d.ts +16 -0
  36. package/dist/src/components/RecentChatsScreen/index.js +38 -0
  37. package/dist/src/components/Tabs/BottomTabs.d.ts +10 -0
  38. package/dist/src/components/Tabs/BottomTabs.js +29 -0
  39. package/dist/src/components/TicketScreen/index.d.ts +9 -0
  40. package/dist/src/components/TicketScreen/index.js +71 -0
  41. package/dist/src/components/UserListScreen/index.d.ts +13 -0
  42. package/dist/src/components/UserListScreen/index.js +64 -0
  43. package/dist/src/config/index.d.ts +3 -0
  44. package/dist/src/config/index.js +38 -0
  45. package/dist/src/hooks/useChat.d.ts +8 -0
  46. package/dist/src/hooks/useChat.js +26 -0
  47. package/dist/src/hooks/useUsers.d.ts +7 -0
  48. package/dist/src/hooks/useUsers.js +26 -0
  49. package/dist/src/index.d.ts +14 -0
  50. package/dist/src/index.js +13 -0
  51. package/dist/src/services/userService.d.ts +2 -0
  52. package/dist/src/services/userService.js +9 -0
  53. package/dist/src/types/index.d.ts +59 -0
  54. package/dist/src/types/index.js +1 -0
  55. package/dist/src/utils/theme.d.ts +3 -0
  56. package/dist/src/utils/theme.js +13 -0
  57. package/dist/types/index.d.ts +23 -36
  58. package/dist/utils/theme.d.ts +0 -1
  59. package/dist/utils/theme.js +3 -18
  60. package/package.json +10 -20
  61. package/src/components/ChatScreen/index.tsx +205 -0
  62. package/src/components/ChatWidget.tsx +327 -0
  63. package/src/components/HomeScreen/index.tsx +130 -0
  64. package/src/components/MaintenanceView/index.tsx +41 -0
  65. package/src/components/RecentChatsScreen/index.tsx +108 -0
  66. package/src/components/Tabs/BottomTabs.tsx +82 -0
  67. package/src/components/TicketScreen/index.tsx +170 -0
  68. package/src/components/UserListScreen/index.tsx +181 -0
  69. package/src/config/index.ts +46 -0
  70. package/src/hooks/useChat.ts +31 -0
  71. package/src/hooks/useUsers.ts +27 -0
  72. package/src/index.ts +18 -0
  73. package/src/services/userService.ts +9 -0
  74. package/src/types/index.ts +82 -0
  75. package/src/utils/theme.ts +16 -0
  76. package/dist/components/BottomNav/index.d.ts +0 -10
  77. package/dist/components/BottomNav/index.js +0 -32
  78. package/dist/components/ChatBox/index.d.ts +0 -15
  79. package/dist/components/ChatBox/index.js +0 -228
  80. package/dist/components/ChatButton/index.d.ts +0 -9
  81. package/dist/components/ChatButton/index.js +0 -17
  82. package/dist/components/ChatWindow/index.d.ts +0 -10
  83. package/dist/components/ChatWindow/index.js +0 -286
  84. package/dist/components/HomeView/index.d.ts +0 -12
  85. package/dist/components/HomeView/index.js +0 -51
  86. package/dist/components/UserList/index.d.ts +0 -13
  87. package/dist/components/UserList/index.js +0 -136
package/README.md CHANGED
@@ -1,157 +1,81 @@
1
- # Chat Widget
1
+ # react-chat-widget-extension v2
2
2
 
3
- A reusable, fully configurable floating chat widget for **React.js** and **Next.js** applications.
4
-
5
- - ✅ Environment-variable-driven behavior (status, type, API endpoint)
6
- - ✅ Fully themeable via a `theme` prop (colors, fonts, button, position)
7
- - ✅ SSR-safe — works with Next.js App Router and Pages Router
8
- - ✅ TypeScript-first
9
- - ✅ WebSocket-ready architecture
10
- - ✅ Loading skeletons, empty states, error handling built in
3
+ A drop-in floating chat widget for **React.js** and **Next.js** with a multi-screen UI, ticket system, and full theme control.
11
4
 
12
5
  ---
13
6
 
14
- ## Folder Structure
7
+ ## Screens & Navigation Flow
15
8
 
16
9
  ```
17
- my_first_project/
18
- ├── src/
19
- ├── index.ts # Public API exports
20
- ├── types/
21
- │ └── index.ts # All TypeScript types & interfaces
22
- ├── config/
23
- │ └── index.ts # Env variable loader (Next.js + React safe)
24
- ├── services/
25
- │ │ └── userService.ts # Fetch users from API
26
- │ ├── hooks/
27
- │ │ ├── useUsers.ts # Fetch & filter users hook
28
- │ │ └── useChat.ts # Chat state & message management hook
29
- │ ├── utils/
30
- │ │ └── theme.ts # Theme merging & CSS variable utilities
31
- │ └── components/
32
- │ ├── ChatWidget.tsx # 🏠 Root widget — mount this in your app
33
- │ ├── ChatButton/
34
- │ │ └── index.tsx # Floating action button
35
- │ ├── ChatWindow/
36
- │ │ └── index.tsx # Expandable chat panel
37
- │ ├── UserList/
38
- │ │ └── index.tsx # User list with loading/error/empty states
39
- │ ├── ChatBox/
40
- │ │ └── index.tsx # Conversation panel + message input
41
- │ └── MaintenanceView/
42
- │ └── index.tsx # Shown when CHAT_STATUS=MAINTENANCE
43
- ├── examples/
44
- │ ├── react-app/
45
- │ │ ├── .env.example # React env variables template
46
- │ │ └── App.tsx # React usage example
47
- │ └── nextjs-app/
48
- │ ├── .env.local.example # Next.js env variables template
49
- │ ├── app/
50
- │ │ ├── layout.tsx # App Router: root layout
51
- │ │ ├── ChatWidgetWrapper.tsx # App Router: 'use client' boundary
52
- │ │ └── page.tsx # App Router: home page
53
- │ └── pages/
54
- │ ├── _app.tsx # Pages Router: global app
55
- │ └── index.tsx # Pages Router: index page
56
- ├── package.json
57
- ├── tsconfig.json
58
- └── README.md
59
- ```
60
-
61
- ---
62
-
63
- ## Installation
64
-
65
- ```bash
66
- npm install ajaxter-chat
67
- # or
68
- yarn add ajaxter-chat
10
+ Floating Button
11
+ └── Opens Widget Window
12
+ ├── [Home Screen] ← default on open
13
+ ├── Need Support → [User List Screen: developers] → [Chat Screen]
14
+ ├── New Convo → [User List Screen: users] → [Chat Screen]
15
+ └── Raise Ticket [Ticket Screen] (always shown)
16
+
17
+ ├── [Bottom Tab: Home] ← Home screen
18
+ ├── [Bottom Tab: Chats] ← Recent conversations list
19
+ └── [Bottom Tab: Tickets] ← All raised tickets + new ticket form
69
20
  ```
70
21
 
71
22
  ---
72
23
 
73
24
  ## Environment Variables
74
25
 
75
- ### React.js (.env)
76
-
26
+ ### React (.env)
77
27
  ```env
78
28
  REACT_APP_CHAT_HOST_URL=http://your-api.com
79
- REACT_APP_CHAT_HOST_PORT=4000
80
- REACT_APP_CHAT_USER_LIST=api/v1/chat/users
81
- REACT_APP_CHAT_STATUS=ACTIVE
82
- REACT_APP_CHAT_TYPE=BOTH
29
+ REACT_APP_CHAT_HOST_PORT=4000 # Optional — omit to use URL default port
30
+ REACT_APP_CHAT_USER_LIST=api/v1/users
31
+ REACT_APP_CHAT_STATUS=ACTIVE # ACTIVE | DISABLE | MAINTENANCE
32
+ REACT_APP_CHAT_TYPE=BOTH # SUPPORT | CHAT | BOTH
83
33
  ```
84
34
 
85
35
  ### Next.js (.env.local)
86
-
87
36
  ```env
88
37
  NEXT_PUBLIC_CHAT_HOST_URL=http://your-api.com
89
- NEXT_PUBLIC_CHAT_HOST_PORT=4000
90
- NEXT_PUBLIC_CHAT_USER_LIST=api/v1/chat/users
38
+ NEXT_PUBLIC_CHAT_HOST_PORT=4000 # Optional
39
+ NEXT_PUBLIC_CHAT_USER_LIST=api/v1/users
91
40
  NEXT_PUBLIC_CHAT_STATUS=ACTIVE
92
41
  NEXT_PUBLIC_CHAT_TYPE=BOTH
93
42
  ```
94
43
 
95
- ### Variable Reference
96
-
97
- | Variable | Type | Description |
98
- |--------------------|---------------------------------------|------------------------------------------|
99
- | `CHAT_HOST_URL` | string | Base URL of your chat/user API |
100
- | `CHAT_HOST_PORT` | number | Port for your API server |
101
- | `CHAT_USER_LIST` | string | Endpoint path to fetch users |
102
- | `CHAT_STATUS` | `ACTIVE` \| `DISABLE` \| `MAINTENANCE` | Controls widget visibility & state |
103
- | `CHAT_TYPE` | `SUPPORT` \| `CHAT` \| `BOTH` | Controls which users are shown |
104
-
105
44
  ---
106
45
 
107
- ## CHAT_STATUS Behavior
46
+ ## CHAT_STATUS Behaviour
108
47
 
109
- | Value | Behavior |
110
- |-----------------|---------------------------------------------------------------|
111
- | `ACTIVE` | Widget is fully enabled |
112
- | `DISABLE` | Widget is **not rendered at all** — zero DOM footprint |
113
- | `MAINTENANCE` | Widget opens but shows a maintenance message (non-interactive)|
48
+ | Value | Behaviour |
49
+ |---------------|--------------------------------------------------------|
50
+ | `ACTIVE` | Widget fully enabled |
51
+ | `DISABLE` | Widget **not rendered at all** — zero DOM footprint |
52
+ | `MAINTENANCE` | Widget opens but shows a maintenance message |
114
53
 
115
54
  ---
116
55
 
117
- ## CHAT_TYPE Behavior
56
+ ## CHAT_TYPE Behaviour
118
57
 
119
- | Value | User List Shown | UI |
120
- |-----------|------------------------------------------|-----------------------------|
121
- | `SUPPORT` | Only `type: "developer"` users | Single panel |
122
- | `CHAT` | Only `type: "user"` users | Single panel |
123
- | `BOTH` | Both developers and users | Two tabs (Support / Users) |
58
+ | Value | Home Cards Shown | User List Filter |
59
+ |-----------|-------------------------------------|-------------------|
60
+ | `SUPPORT` | Need Support only | `type=developer` |
61
+ | `CHAT` | New Conversation only | `type=user` |
62
+ | `BOTH` | Both cards | Per card clicked |
63
+
64
+ > **Raise Ticket is always shown regardless of CHAT_TYPE.**
124
65
 
125
66
  ---
126
67
 
127
68
  ## User List API
128
69
 
129
- The widget fetches users from:
130
-
131
70
  ```
132
- GET ${CHAT_HOST_URL}:${CHAT_HOST_PORT}/${CHAT_USER_LIST}
71
+ GET {CHAT_HOST_URL}[:{CHAT_HOST_PORT}]/{CHAT_USER_LIST}
133
72
  ```
134
73
 
135
74
  Expected response:
136
-
137
75
  ```json
138
76
  [
139
- {
140
- "name": "Alice Dev",
141
- "uid": "uid_001",
142
- "email": "alice@company.com",
143
- "mobile": "+1234567890",
144
- "project": "Platform Team",
145
- "type": "developer"
146
- },
147
- {
148
- "name": "Bob Smith",
149
- "uid": "uid_002",
150
- "email": "bob@client.com",
151
- "mobile": "+0987654321",
152
- "project": "Client Portal",
153
- "type": "user"
154
- }
77
+ { "name": "Alice", "uid": "u1", "email": "alice@co.com", "mobile": "", "project": "Platform", "type": "developer" },
78
+ { "name": "Bob", "uid": "u2", "email": "bob@co.com", "mobile": "", "project": "Portal", "type": "user" }
155
79
  ]
156
80
  ```
157
81
 
@@ -159,132 +83,113 @@ Expected response:
159
83
 
160
84
  ## Usage
161
85
 
162
- ### React.js
163
-
86
+ ### React
164
87
  ```tsx
165
88
  // App.tsx
166
- import { ChatWidget } from 'ajaxter-chat';
89
+ import { ChatWidget } from 'react-chat-widget-extension';
167
90
 
168
- function App() {
91
+ export default function App() {
169
92
  return (
170
- <div>
171
- <main>Your app content</main>
172
-
93
+ <>
94
+ <main>Your app</main>
173
95
  <ChatWidget
174
96
  theme={{
175
- primaryColor: '#6C63FF',
176
- buttonColor: '#6C63FF',
177
- buttonTextColor: '#ffffff',
178
- buttonLabel: 'Chat with us',
97
+ primaryColor: '#1aaa96',
98
+ buttonLabel: 'Chat with us',
179
99
  buttonPosition: 'bottom-right',
180
- fontFamily: "'DM Sans', sans-serif",
181
- borderRadius: '16px',
182
100
  }}
183
101
  />
184
- </div>
102
+ </>
185
103
  );
186
104
  }
187
105
  ```
188
106
 
189
107
  ### Next.js — App Router
190
-
191
108
  ```tsx
192
109
  // app/ChatWidgetWrapper.tsx
193
110
  'use client';
194
- import { ChatWidget } from 'ajaxter-chat';
195
-
111
+ import { ChatWidget } from 'react-chat-widget-extension';
196
112
  export function ChatWidgetWrapper() {
197
- return <ChatWidget theme={{ primaryColor: '#0ea5e9' }} />;
113
+ return <ChatWidget theme={{ primaryColor: '#1aaa96' }} />;
198
114
  }
199
- ```
200
115
 
201
- ```tsx
202
116
  // app/layout.tsx
203
117
  import { ChatWidgetWrapper } from './ChatWidgetWrapper';
204
-
205
118
  export default function RootLayout({ children }) {
206
- return (
207
- <html lang="en">
208
- <body>
209
- {children}
210
- <ChatWidgetWrapper />
211
- </body>
212
- </html>
213
- );
119
+ return <html><body>{children}<ChatWidgetWrapper /></body></html>;
214
120
  }
215
121
  ```
216
122
 
217
123
  ### Next.js — Pages Router
218
-
219
124
  ```tsx
220
125
  // pages/_app.tsx
221
- import { ChatWidget } from 'ajaxter-chat';
222
-
126
+ import { ChatWidget } from 'react-chat-widget-extension';
223
127
  export default function MyApp({ Component, pageProps }) {
224
- return (
225
- <>
226
- <Component {...pageProps} />
227
- <ChatWidget theme={{ primaryColor: '#10b981' }} />
228
- </>
229
- );
128
+ return <><Component {...pageProps} /><ChatWidget theme={{ primaryColor: '#1aaa96' }} /></>;
230
129
  }
231
130
  ```
232
131
 
233
132
  ---
234
133
 
235
- ## Theme Props
134
+ ## Theme Props (all optional)
236
135
 
237
- All theme properties are **optional**. Defaults are used when omitted.
238
-
239
- ```tsx
240
- interface ChatWidgetTheme {
241
- fontFamily?: string; // Default: "'DM Sans', 'Segoe UI', sans-serif"
242
- primaryColor?: string; // Default: '#6C63FF' header, accents, active states
243
- backgroundColor?: string; // Default: '#ffffff' widget panel background
244
- buttonColor?: string; // Default: '#6C63FF' floating button background
245
- buttonTextColor?: string; // Default: '#ffffff' floating button text/icon color
246
- buttonLabel?: string; // Default: 'Chat with us'
247
- buttonPosition?: 'bottom-right' | 'bottom-left'; // Default: 'bottom-right'
248
- borderRadius?: string; // Default: '16px'
249
- }
250
- ```
136
+ | Prop | Type | Default | Description |
137
+ |-------------------|------------------------------------|----------------------------------|--------------------------------------|
138
+ | `primaryColor` | `string` | `'#1aaa96'` | Header, active states, send button |
139
+ | `buttonColor` | `string` | `'#1aaa96'` | Floating button background |
140
+ | `buttonTextColor` | `string` | `'#ffffff'` | Floating button text/icon |
141
+ | `buttonLabel` | `string` | `'Chat with us'` | Floating button label |
142
+ | `buttonPosition` | `'bottom-right' \| 'bottom-left'` | `'bottom-right'` | Floating button corner |
143
+ | `fontFamily` | `string` | `"'DM Sans', 'Segoe UI', ..."` | Font used across the widget |
144
+ | `borderRadius` | `string` | `'16px'` | Widget panel corner radius |
145
+ | `backgroundColor` | `string` | `'#ffffff'` | Widget panel background |
251
146
 
252
147
  ---
253
148
 
254
- ## WebSocket Integration
149
+ ## Folder Structure
255
150
 
256
- The `useChat` hook is ready for WebSocket integration. Look for the `TODO` comments in:
151
+ ```
152
+ src/
153
+ ├── index.ts ← Public API exports
154
+ ├── types/index.ts ← All TypeScript types
155
+ ├── config/index.ts ← Env loader (NEXT_PUBLIC_ + REACT_APP_)
156
+ ├── services/userService.ts ← fetch() user list API
157
+ ├── hooks/
158
+ │ ├── useUsers.ts ← Fetch & filter users
159
+ │ └── useChat.ts ← Message state, WebSocket-ready
160
+ ├── utils/theme.ts ← defaultTheme + mergeTheme
161
+ └── components/
162
+ ├── ChatWidget.tsx ← 🏠 Root — mount this in your app
163
+ ├── HomeScreen/ ← Hi there + option cards
164
+ ├── UserListScreen/ ← Slide-in user picker
165
+ ├── ChatScreen/ ← Conversation + input bar
166
+ ├── RecentChatsScreen/ ← Bottom tab: Chats
167
+ ├── TicketScreen/ ← Bottom tab: Tickets + raise form
168
+ ├── MaintenanceView/ ← Shown when MAINTENANCE
169
+ └── Tabs/BottomTabs.tsx ← Home / Chats / Tickets tabs
170
+ ```
257
171
 
258
- - `src/hooks/useChat.ts` → Add `socket.emit('message', newMsg)` in `sendMessage`
259
- - `src/hooks/useChat.ts` → Add `socket.on('message', ...)` listener in `selectUser`
260
- - `src/components/ChatWindow/index.tsx` → Initialize socket connection on mount
172
+ ---
261
173
 
262
- Example with socket.io:
174
+ ## WebSocket Integration Points
175
+
176
+ Look for `// TODO:` comments in `src/hooks/useChat.ts`:
263
177
 
264
178
  ```ts
265
- // In useChat.tssendMessage
266
- socket.emit('chat:message', { to: activeUser.uid, text });
179
+ // In selectUserconnect and listen:
180
+ // socket.emit('join', user.uid);
181
+ // socket.on('message', (msg) => setMessages(prev => [...prev, msg]));
267
182
 
268
- // In useChat.tsselectUser
269
- socket.on('chat:message', (msg: ChatMessage) => {
270
- setMessages((prev) => [...prev, msg]);
271
- });
183
+ // In sendMessageemit outgoing:
184
+ // socket.emit('message', newMsg);
272
185
  ```
273
186
 
274
187
  ---
275
188
 
276
- ## Build
277
-
278
- ```bash
279
- cd my_first_project
280
- npm install
281
- npm run build # Compile TypeScript → dist/
282
- npm run type-check # Verify types without emitting
283
- npm run dev # Watch mode
284
- ```
285
-
286
- ---
189
+ ## Resize (Maximize / Minimize)
287
190
 
288
- ## License
191
+ The widget has a maximize/minimize toggle button in the top-right of the panel header.
192
+ - **Normal size**: 380×560px
193
+ - **Maximized**: 480×720px
194
+ - Both sizes respect `max-width: calc(100vw - 32px)` and `max-height: calc(100vh - 110px)` for mobile safety.
289
195
 
290
- MIT
@@ -0,0 +1,12 @@
1
+ import React from 'react';
2
+ import { ChatMessage, ChatUser, ChatWidgetTheme } from '../../types';
3
+ interface ChatScreenProps {
4
+ activeUser: ChatUser;
5
+ messages: ChatMessage[];
6
+ onSend: (text: string) => void;
7
+ onBack: () => void;
8
+ onClose: () => void;
9
+ theme?: ChatWidgetTheme;
10
+ }
11
+ export declare const ChatScreen: React.FC<ChatScreenProps>;
12
+ export {};
@@ -0,0 +1,83 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState, useRef, useEffect } from 'react';
3
+ import { mergeTheme } from '../../utils/theme';
4
+ export const ChatScreen = ({ activeUser, messages, onSend, onBack, onClose, theme, }) => {
5
+ const t = mergeTheme(theme);
6
+ const [text, setText] = useState('');
7
+ const endRef = useRef(null);
8
+ const inputRef = useRef(null);
9
+ useEffect(() => { var _a; (_a = endRef.current) === null || _a === void 0 ? void 0 : _a.scrollIntoView({ behavior: 'smooth' }); }, [messages]);
10
+ const handleSend = () => {
11
+ var _a;
12
+ if (!text.trim())
13
+ return;
14
+ onSend(text);
15
+ setText('');
16
+ (_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
17
+ };
18
+ const handleKey = (e) => {
19
+ if (e.key === 'Enter' && !e.shiftKey) {
20
+ e.preventDefault();
21
+ handleSend();
22
+ }
23
+ };
24
+ const initials = activeUser.name.split(' ').map(n => n[0]).join('').toUpperCase().slice(0, 2);
25
+ return (_jsxs("div", { style: { display: 'flex', flexDirection: 'column', height: '100%', animation: 'cw-slideInRight 0.25s ease' }, children: [_jsxs("div", { style: {
26
+ backgroundColor: t.primaryColor,
27
+ padding: '14px 18px',
28
+ display: 'flex',
29
+ alignItems: 'center',
30
+ gap: '10px',
31
+ flexShrink: 0,
32
+ }, children: [_jsx("button", { onClick: onBack, style: iconBtnStyle, children: _jsx("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", children: _jsx("path", { d: "M19 12H5M5 12L12 19M5 12L12 5", stroke: "#fff", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round" }) }) }), _jsx("div", { style: {
33
+ width: 36, height: 36, borderRadius: '50%',
34
+ backgroundColor: 'rgba(255,255,255,0.25)',
35
+ display: 'flex', alignItems: 'center', justifyContent: 'center',
36
+ fontWeight: 700, fontSize: '13px', color: '#fff', flexShrink: 0,
37
+ }, children: initials }), _jsxs("div", { style: { flex: 1, minWidth: 0 }, children: [_jsx("div", { style: { fontWeight: 700, fontSize: '14px', color: '#fff', fontFamily: t.fontFamily }, children: activeUser.name }), _jsxs("div", { style: { fontSize: '11px', color: 'rgba(255,255,255,0.8)', display: 'flex', alignItems: 'center', gap: 4 }, children: [_jsx("span", { style: { width: 6, height: 6, borderRadius: '50%', backgroundColor: '#a8f0c6', display: 'inline-block' } }), "Online"] })] }), _jsx("button", { onClick: onClose, style: iconBtnStyle, children: _jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", children: _jsx("path", { d: "M18 6L6 18M6 6l12 12", stroke: "#fff", strokeWidth: "2.5", strokeLinecap: "round" }) }) })] }), _jsxs("div", { style: {
38
+ flex: 1, overflowY: 'auto', padding: '18px 16px',
39
+ display: 'flex', flexDirection: 'column', gap: '10px',
40
+ backgroundColor: '#f7f8fc',
41
+ }, children: [messages.length === 0 && (_jsxs("div", { style: {
42
+ margin: 'auto', textAlign: 'center',
43
+ fontSize: '13px', color: '#b0bec5',
44
+ fontFamily: t.fontFamily,
45
+ }, children: [_jsx("div", { style: { fontSize: '28px', marginBottom: 8 }, children: "\uD83D\uDCAC" }), "Say hi to ", activeUser.name, "!"] })), messages.map(msg => (_jsx(Bubble, { msg: msg, primaryColor: t.primaryColor, font: t.fontFamily }, msg.id))), _jsx("div", { ref: endRef })] }), _jsxs("div", { style: {
46
+ borderTop: '1px solid #eef0f5',
47
+ padding: '10px 14px',
48
+ backgroundColor: '#fff',
49
+ display: 'flex',
50
+ alignItems: 'flex-end',
51
+ gap: '10px',
52
+ flexShrink: 0,
53
+ }, children: [_jsx("textarea", { ref: inputRef, value: text, onChange: e => setText(e.target.value), onKeyDown: handleKey, placeholder: "Type and press [enter]..", rows: 1, style: {
54
+ flex: 1, resize: 'none', border: 'none', outline: 'none',
55
+ fontFamily: t.fontFamily, fontSize: '14px', lineHeight: '1.5',
56
+ maxHeight: '80px', overflowY: 'auto', color: '#1a2332',
57
+ padding: '6px 0', backgroundColor: 'transparent',
58
+ } }), _jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: '8px', flexShrink: 0 }, children: [_jsx(IconBtn, { onClick: () => { }, title: "Reaction", children: _jsxs("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", children: [_jsx("path", { d: "M14 9h.01M10 9h.01M12 2a10 10 0 100 20A10 10 0 0012 2zm0 14s-4-1.5-4-4", stroke: "#9aa3af", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round" }), _jsx("path", { d: "M8 15s1.5 2 4 2 4-2 4-2", stroke: "#9aa3af", strokeWidth: "1.8", strokeLinecap: "round" })] }) }), _jsx(IconBtn, { onClick: () => { }, title: "Attach", children: _jsx("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", children: _jsx("path", { d: "M21.44 11.05l-9.19 9.19a6 6 0 01-8.49-8.49l9.19-9.19a4 4 0 015.66 5.66L9.41 17.41a2 2 0 01-2.83-2.83l8.49-8.48", stroke: "#9aa3af", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round" }) }) }), _jsx(IconBtn, { onClick: () => { }, title: "Emoji", children: _jsxs("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", children: [_jsx("circle", { cx: "12", cy: "12", r: "10", stroke: "#9aa3af", strokeWidth: "1.8" }), _jsx("path", { d: "M8 14s1.5 2 4 2 4-2 4-2", stroke: "#9aa3af", strokeWidth: "1.8", strokeLinecap: "round" }), _jsx("line", { x1: "9", y1: "9", x2: "9.01", y2: "9", stroke: "#9aa3af", strokeWidth: "2.5", strokeLinecap: "round" }), _jsx("line", { x1: "15", y1: "9", x2: "15.01", y2: "9", stroke: "#9aa3af", strokeWidth: "2.5", strokeLinecap: "round" })] }) }), text.trim() && (_jsx("button", { onClick: handleSend, style: {
59
+ width: 36, height: 36, borderRadius: '50%',
60
+ backgroundColor: t.primaryColor, border: 'none',
61
+ cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center',
62
+ transition: 'transform 0.15s',
63
+ }, children: _jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", children: _jsx("path", { d: "M22 2L11 13M22 2L15 22L11 13L2 9L22 2Z", stroke: "#fff", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }) }))] })] })] }));
64
+ };
65
+ const Bubble = ({ msg, primaryColor, font }) => {
66
+ const isMe = msg.senderId === 'me';
67
+ const time = new Date(msg.timestamp).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
68
+ return (_jsxs("div", { style: { display: 'flex', flexDirection: 'column', alignItems: isMe ? 'flex-end' : 'flex-start', gap: 3 }, children: [_jsx("div", { style: {
69
+ maxWidth: '75%', padding: '10px 14px',
70
+ borderRadius: isMe ? '18px 18px 4px 18px' : '18px 18px 18px 4px',
71
+ backgroundColor: isMe ? primaryColor : '#fff',
72
+ color: isMe ? '#fff' : '#1a2332',
73
+ fontSize: '14px', lineHeight: '1.5',
74
+ boxShadow: '0 1px 4px rgba(0,0,0,0.07)',
75
+ fontFamily: font, wordBreak: 'break-word',
76
+ }, children: msg.text }), _jsx("span", { style: { fontSize: '11px', color: '#b0bec5', padding: '0 4px' }, children: time })] }));
77
+ };
78
+ const IconBtn = ({ onClick, title, children }) => (_jsx("button", { onClick: onClick, title: title, style: { background: 'none', border: 'none', cursor: 'pointer', padding: '4px', display: 'flex', alignItems: 'center', borderRadius: '6px' }, onMouseEnter: e => e.currentTarget.style.background = '#f3f4f6', onMouseLeave: e => e.currentTarget.style.background = 'none', children: children }));
79
+ const iconBtnStyle = {
80
+ background: 'rgba(255,255,255,0.2)', border: 'none', borderRadius: '50%',
81
+ width: 34, height: 34, display: 'flex', alignItems: 'center', justifyContent: 'center',
82
+ cursor: 'pointer', flexShrink: 0,
83
+ };
@@ -1,28 +1,4 @@
1
1
  import React from 'react';
2
2
  import { ChatWidgetProps } from '../types';
3
- /**
4
- * ChatWidget
5
- *
6
- * Drop-in chat widget for React.js and Next.js apps.
7
- * All behavior is configured via environment variables.
8
- * All UI styling is configured via the `theme` prop.
9
- *
10
- * @example
11
- * // Basic usage
12
- * <ChatWidget />
13
- *
14
- * @example
15
- * // With custom theme
16
- * <ChatWidget
17
- * theme={{
18
- * primaryColor: '#FF6B6B',
19
- * buttonColor: '#FF6B6B',
20
- * buttonLabel: 'Need Help?',
21
- * buttonPosition: 'bottom-left',
22
- * fontFamily: "'Inter', sans-serif",
23
- * borderRadius: '12px',
24
- * }}
25
- * />
26
- */
27
3
  export declare const ChatWidget: React.FC<ChatWidgetProps>;
28
4
  export default ChatWidget;