@enjoys/react-chatbot-plugin 1.2.0 → 1.4.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/README.md +84 -436
- package/dist/index.cjs +5 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +116 -1
- package/dist/index.mjs +5 -2684
- package/dist/index.mjs.map +1 -1
- package/package.json +33 -3
package/README.md
CHANGED
|
@@ -1,12 +1,46 @@
|
|
|
1
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="./image.png" alt="React ChatBot Plugin — Customizable Chat Widget for React" width="100%" />
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<p align="center">
|
|
6
|
+
<a href="https://github.com/enjoys-in/react-chatbot-plugin">
|
|
7
|
+
<img src="https://opengraph.githubassets.com/1/enjoys-in/react-chatbot-plugin" alt="GitHub Social Preview" width="100%" />
|
|
8
|
+
</a>
|
|
9
|
+
</p>
|
|
10
|
+
|
|
11
|
+
<p align="center">
|
|
12
|
+
<img src="https://img.shields.io/npm/v/@enjoys/react-chatbot-plugin?color=6C5CE7&style=for-the-badge" alt="npm version" />
|
|
13
|
+
<img src="https://img.shields.io/npm/dm/@enjoys/react-chatbot-plugin?color=A29BFE&style=for-the-badge" alt="npm downloads" />
|
|
14
|
+
<img src="https://img.shields.io/bundlephobia/minzip/@enjoys/react-chatbot-plugin?color=00b894&style=for-the-badge" alt="bundle size" />
|
|
15
|
+
<img src="https://img.shields.io/npm/l/@enjoys/react-chatbot-plugin?color=fd79a8&style=for-the-badge" alt="license" />
|
|
16
|
+
<img src="https://img.shields.io/github/stars/enjoys-in/react-chatbot-plugin?color=fdcb6e&style=for-the-badge" alt="stars" />
|
|
17
|
+
</p>
|
|
18
|
+
|
|
19
|
+
<h1 align="center">@enjoys/react-chatbot-plugin</h1>
|
|
20
|
+
|
|
21
|
+
<p align="center">
|
|
22
|
+
<strong>A fully customizable, plugin-based chatbot widget for React.</strong><br/>
|
|
23
|
+
Like tawk.to — but open-source and fully programmable.
|
|
24
|
+
</p>
|
|
25
|
+
|
|
26
|
+
<p align="center">
|
|
27
|
+
<a href="https://www.npmjs.com/package/@enjoys/react-chatbot-plugin"><b>npm</b></a> ·
|
|
28
|
+
<a href="#quick-start"><b>Quick Start</b></a> ·
|
|
29
|
+
<a href="#documentation"><b>Docs</b></a> ·
|
|
30
|
+
<a href="https://github.com/enjoys-in/react-chatbot-plugin/issues">Report Bug</a> ·
|
|
31
|
+
<a href="https://github.com/enjoys-in/react-chatbot-plugin/issues">Request Feature</a>
|
|
32
|
+
</p>
|
|
33
|
+
|
|
34
|
+
---
|
|
2
35
|
|
|
3
|
-
A customizable, plugin-based chatbot widget for React — like tawk.to but fully programmable.
|
|
4
|
-
|
|
5
|
-
[](https://www.npmjs.com/package/@enjoys/react-chatbot-plugin)
|
|
6
36
|
|
|
7
37
|
## Features
|
|
8
38
|
|
|
9
39
|
- **JSON-driven flows** — Build conversational UIs with step-based JSON configuration
|
|
40
|
+
- **Keyword matching** — Route user text to responses or flow steps via pattern matching
|
|
41
|
+
- **Greeting detection** — Auto-respond to common greetings (hi, hello, hey, etc.)
|
|
42
|
+
- **Fallback responses** — Catch-all reply when no keyword or flow matches
|
|
43
|
+
- **Input validation** — Validate free-text input inside flow steps with transforms
|
|
10
44
|
- **Async actions** — Run API calls on step entry with real-time loading/progress/error states
|
|
11
45
|
- **Custom step components** — Render your own React widgets inside flow steps
|
|
12
46
|
- **Dynamic routing** — Route to different steps based on API results, status codes, or custom logic
|
|
@@ -14,17 +48,24 @@ A customizable, plugin-based chatbot widget for React — like tawk.to but fully
|
|
|
14
48
|
- **Slash commands** — `/help`, `/back`, `/cancel`, `/restart` built-in
|
|
15
49
|
- **Custom header/input** — Swap the header or input with your own React components
|
|
16
50
|
- **Forms** — Text, select, radio, checkbox, file upload, with validation
|
|
51
|
+
- **Custom form fields** — Replace any form field type with your own React component
|
|
17
52
|
- **Theming** — Light/dark mode, CSS variables, glassmorphism design
|
|
18
53
|
- **File uploads** — Drag & drop, preview, size/count limits
|
|
19
54
|
- **Emoji picker** — Built-in emoji selector
|
|
20
55
|
- **Welcome & login screens** — Optional onboarding flow
|
|
21
56
|
- **Branding** — Customizable footer and header
|
|
57
|
+
- **Typing delay** — Realistic typing pause before bot replies
|
|
58
|
+
- **onUnhandledMessage** — Callback when nothing handles user text
|
|
22
59
|
|
|
23
60
|
## Installation
|
|
24
61
|
|
|
25
62
|
```bash
|
|
26
63
|
npm install @enjoys/react-chatbot-plugin
|
|
27
64
|
# or
|
|
65
|
+
yarn add @enjoys/react-chatbot-plugin
|
|
66
|
+
# or
|
|
67
|
+
pnpm add @enjoys/react-chatbot-plugin
|
|
68
|
+
# or
|
|
28
69
|
bun add @enjoys/react-chatbot-plugin
|
|
29
70
|
```
|
|
30
71
|
|
|
@@ -57,14 +98,32 @@ function App() {
|
|
|
57
98
|
<ChatBot
|
|
58
99
|
flow={flow}
|
|
59
100
|
header={{ title: 'Acme Support', subtitle: 'Online', showRestart: true }}
|
|
60
|
-
callbacks={{
|
|
61
|
-
onFlowEnd: (data) => console.log('Flow ended:', data),
|
|
62
|
-
}}
|
|
63
101
|
/>
|
|
64
102
|
);
|
|
65
103
|
}
|
|
66
104
|
```
|
|
67
105
|
|
|
106
|
+
## Documentation
|
|
107
|
+
|
|
108
|
+
Full documentation is available in the [`docs/`](./docs/) folder:
|
|
109
|
+
|
|
110
|
+
| # | Guide | Description |
|
|
111
|
+
|---|-------|-------------|
|
|
112
|
+
| 1 | [Getting Started](./docs/getting-started.md) | Installation, quick start, minimal example |
|
|
113
|
+
| 2 | [Basic Flows](./docs/basic-flows.md) | Steps, messages, quick replies, delays |
|
|
114
|
+
| 3 | [Forms & Validation](./docs/forms.md) | All 15 field types, validation rules, login forms |
|
|
115
|
+
| 4 | [Conditional Branching](./docs/conditional-branching.md) | If/else routing based on collected data |
|
|
116
|
+
| 5 | [Async Actions](./docs/async-actions.md) | API calls, progress messages, error handling |
|
|
117
|
+
| 6 | [Custom Components](./docs/custom-components.md) | React widgets inside flow steps |
|
|
118
|
+
| 7 | [Dynamic Routing](./docs/dynamic-routing.md) | Route based on API response status |
|
|
119
|
+
| 8 | [Theming & Styling](./docs/theming.md) | Colors, CSS variables, dark mode |
|
|
120
|
+
| 9 | [Plugins](./docs/plugins.md) | Built-in & custom plugins |
|
|
121
|
+
| 10 | [Slash Commands](./docs/slash-commands.md) | /help, /back, /restart, /cancel |
|
|
122
|
+
| 11 | [File Upload](./docs/file-upload.md) | Drag & drop, restrictions, previews |
|
|
123
|
+
| 12 | [Custom Header & Input](./docs/custom-header-input.md) | Replace header/input with React components |
|
|
124
|
+
| 13 | [Advanced Patterns](./docs/advanced-patterns.md) | E-commerce bot, onboarding wizard, full examples |
|
|
125
|
+
| 14 | [API Reference](./docs/api-reference.md) | All types, props, and exports |
|
|
126
|
+
|
|
68
127
|
## Props
|
|
69
128
|
|
|
70
129
|
| Prop | Type | Description |
|
|
@@ -92,439 +151,16 @@ function App() {
|
|
|
92
151
|
| `launcherIcon` | `ReactNode` | Custom launcher icon |
|
|
93
152
|
| `closeIcon` | `ReactNode` | Custom close icon |
|
|
94
153
|
| `zIndex` | `number` | CSS z-index |
|
|
154
|
+
| `renderFormField` | `FormFieldRenderMap` | Custom renderers for form field types |
|
|
95
155
|
| `className` | `string` | Root element class name |
|
|
96
156
|
|
|
97
|
-
## Conversation Flows
|
|
98
|
-
|
|
99
|
-
Flows are JSON objects with steps. Each step can have messages, quick replies, forms, conditional branching, and delays.
|
|
100
|
-
|
|
101
|
-
```ts
|
|
102
|
-
const flow: FlowConfig = {
|
|
103
|
-
startStep: 'welcome',
|
|
104
|
-
steps: [
|
|
105
|
-
{
|
|
106
|
-
id: 'welcome',
|
|
107
|
-
message: 'Welcome! What brings you here?',
|
|
108
|
-
quickReplies: [
|
|
109
|
-
{ label: 'Buy', value: 'buy', next: 'purchase' },
|
|
110
|
-
{ label: 'Help', value: 'help', next: 'support' },
|
|
111
|
-
],
|
|
112
|
-
},
|
|
113
|
-
{
|
|
114
|
-
id: 'purchase',
|
|
115
|
-
message: 'Great choice!',
|
|
116
|
-
form: {
|
|
117
|
-
id: 'order',
|
|
118
|
-
title: 'Order Details',
|
|
119
|
-
fields: [
|
|
120
|
-
{ name: 'email', type: 'email', label: 'Email', required: true },
|
|
121
|
-
{ name: 'quantity', type: 'number', label: 'Quantity', required: true },
|
|
122
|
-
],
|
|
123
|
-
submitLabel: 'Place Order',
|
|
124
|
-
},
|
|
125
|
-
next: 'thanks',
|
|
126
|
-
},
|
|
127
|
-
{
|
|
128
|
-
id: 'support',
|
|
129
|
-
message: 'Please describe your issue.',
|
|
130
|
-
},
|
|
131
|
-
{
|
|
132
|
-
id: 'thanks',
|
|
133
|
-
message: 'Order placed! We will email you shortly.',
|
|
134
|
-
},
|
|
135
|
-
],
|
|
136
|
-
};
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
### Step Properties
|
|
140
|
-
|
|
141
|
-
| Property | Type | Description |
|
|
142
|
-
|----------|------|-------------|
|
|
143
|
-
| `id` | `string` | Unique step identifier |
|
|
144
|
-
| `message` | `string` | Single bot message |
|
|
145
|
-
| `messages` | `string[]` | Multiple bot messages |
|
|
146
|
-
| `quickReplies` | `FlowQuickReply[]` | Clickable option buttons |
|
|
147
|
-
| `form` | `FormConfig` | Inline form |
|
|
148
|
-
| `next` | `string` | Next step ID (auto-advance) |
|
|
149
|
-
| `delay` | `number` | Typing delay in ms (default: 500) |
|
|
150
|
-
| `condition` | `FlowCondition` | Conditional branching |
|
|
151
|
-
| `component` | `string` | Key into `components` map — renders a custom React widget |
|
|
152
|
-
| `asyncAction` | `FlowAsyncAction` | Async action to run when the step is entered |
|
|
153
|
-
|
|
154
|
-
### Conditional Branching
|
|
155
|
-
|
|
156
|
-
```ts
|
|
157
|
-
{
|
|
158
|
-
id: 'check_age',
|
|
159
|
-
message: 'Checking your age...',
|
|
160
|
-
condition: {
|
|
161
|
-
field: 'age',
|
|
162
|
-
operator: 'gt', // eq, neq, contains, gt, lt
|
|
163
|
-
value: 18,
|
|
164
|
-
then: 'adult_flow',
|
|
165
|
-
else: 'minor_flow',
|
|
166
|
-
},
|
|
167
|
-
}
|
|
168
|
-
```
|
|
169
|
-
|
|
170
|
-
## Async Actions
|
|
171
|
-
|
|
172
|
-
Run API calls, validations, or any async work when a step is entered. The chat shows real-time progress messages and routes based on the result.
|
|
173
|
-
|
|
174
|
-
```tsx
|
|
175
|
-
import type { FlowConfig, FlowActionResult, ActionContext } from '@enjoys/react-chatbot-plugin';
|
|
176
|
-
|
|
177
|
-
const flow: FlowConfig = {
|
|
178
|
-
startStep: 'collect_email',
|
|
179
|
-
steps: [
|
|
180
|
-
{
|
|
181
|
-
id: 'collect_email',
|
|
182
|
-
message: 'Enter your email to verify:',
|
|
183
|
-
form: {
|
|
184
|
-
id: 'email-form',
|
|
185
|
-
title: 'Email Verification',
|
|
186
|
-
fields: [{ name: 'email', type: 'email', label: 'Email', required: true }],
|
|
187
|
-
submitLabel: 'Verify',
|
|
188
|
-
},
|
|
189
|
-
next: 'verify',
|
|
190
|
-
},
|
|
191
|
-
{
|
|
192
|
-
id: 'verify',
|
|
193
|
-
message: 'Starting verification...',
|
|
194
|
-
asyncAction: {
|
|
195
|
-
handler: 'verify-email', // key into actionHandlers
|
|
196
|
-
loadingMessage: '🔄 Verifying...', // shown while running
|
|
197
|
-
successMessage: '✅ Verified!', // shown on success
|
|
198
|
-
errorMessage: '❌ Failed.', // shown on error/throw
|
|
199
|
-
onSuccess: 'done', // next step on success
|
|
200
|
-
onError: 'retry', // next step on error
|
|
201
|
-
},
|
|
202
|
-
},
|
|
203
|
-
{ id: 'done', message: 'Your email is verified! 🎉' },
|
|
204
|
-
{
|
|
205
|
-
id: 'retry',
|
|
206
|
-
message: 'Verification failed. Try again?',
|
|
207
|
-
quickReplies: [
|
|
208
|
-
{ label: 'Retry', value: 'retry', next: 'collect_email' },
|
|
209
|
-
],
|
|
210
|
-
},
|
|
211
|
-
],
|
|
212
|
-
};
|
|
213
|
-
|
|
214
|
-
<ChatBot
|
|
215
|
-
flow={flow}
|
|
216
|
-
actionHandlers={{
|
|
217
|
-
'verify-email': async (data, ctx) => {
|
|
218
|
-
ctx.updateMessage('📡 Contacting server...'); // update status message in real-time
|
|
219
|
-
await fetch('/api/verify', { method: 'POST', body: JSON.stringify(data) });
|
|
220
|
-
ctx.updateMessage('🔐 Validating...');
|
|
221
|
-
// return result — status determines routing
|
|
222
|
-
return { status: 'success', data: { verified: true } };
|
|
223
|
-
},
|
|
224
|
-
}}
|
|
225
|
-
/>
|
|
226
|
-
```
|
|
227
|
-
|
|
228
|
-
### FlowAsyncAction Properties
|
|
229
|
-
|
|
230
|
-
| Property | Type | Description |
|
|
231
|
-
|----------|------|-------------|
|
|
232
|
-
| `handler` | `string` | Key into `actionHandlers` prop |
|
|
233
|
-
| `loadingMessage` | `string` | Message shown while running (default: "Processing...") |
|
|
234
|
-
| `successMessage` | `string` | Message shown on success |
|
|
235
|
-
| `errorMessage` | `string` | Message shown on error or exception |
|
|
236
|
-
| `onSuccess` | `string` | Next step ID on success |
|
|
237
|
-
| `onError` | `string` | Next step ID on error |
|
|
238
|
-
| `routes` | `Record<string, string>` | Map of `result.status` → step ID for custom routing |
|
|
239
|
-
|
|
240
|
-
### ActionContext
|
|
241
|
-
|
|
242
|
-
| Method | Description |
|
|
243
|
-
|--------|-------------|
|
|
244
|
-
| `updateMessage(text)` | Update the loading/status message text in real-time |
|
|
245
|
-
|
|
246
|
-
### FlowActionResult
|
|
247
|
-
|
|
248
|
-
Returned by action handlers to control routing and data:
|
|
249
|
-
|
|
250
|
-
| Property | Type | Description |
|
|
251
|
-
|----------|------|-------------|
|
|
252
|
-
| `status` | `string` | `'success'`, `'error'`, or any custom string for route matching |
|
|
253
|
-
| `data` | `Record<string, unknown>` | Data to merge into collected data |
|
|
254
|
-
| `message` | `string` | Override the success/error message |
|
|
255
|
-
| `next` | `string` | Override all routing — go directly to this step |
|
|
256
|
-
|
|
257
|
-
**Routing priority:** `result.next` → `routes[status]` → `onSuccess/onError` → `step.next`
|
|
258
|
-
|
|
259
|
-
## Custom Step Components
|
|
260
|
-
|
|
261
|
-
Render your own interactive React widgets inside flow steps. Components receive collected data and an `onComplete` callback to continue the flow.
|
|
262
|
-
|
|
263
|
-
```tsx
|
|
264
|
-
import type { StepComponentProps } from '@enjoys/react-chatbot-plugin';
|
|
265
|
-
|
|
266
|
-
const PlanSelector: React.FC<StepComponentProps> = ({ data, onComplete }) => (
|
|
267
|
-
<div>
|
|
268
|
-
<p>Hi {data.name as string}! Choose a plan:</p>
|
|
269
|
-
<button onClick={() => onComplete({ status: 'success', data: { plan: 'basic' }, next: 'basic_info' })}>
|
|
270
|
-
Basic — $9/mo
|
|
271
|
-
</button>
|
|
272
|
-
<button onClick={() => onComplete({ status: 'success', data: { plan: 'pro' }, next: 'pro_info' })}>
|
|
273
|
-
Pro — $29/mo
|
|
274
|
-
</button>
|
|
275
|
-
</div>
|
|
276
|
-
);
|
|
277
|
-
|
|
278
|
-
const flow: FlowConfig = {
|
|
279
|
-
startStep: 'choose_plan',
|
|
280
|
-
steps: [
|
|
281
|
-
{
|
|
282
|
-
id: 'choose_plan',
|
|
283
|
-
message: 'Select your plan:',
|
|
284
|
-
component: 'PlanSelector', // key into components map
|
|
285
|
-
},
|
|
286
|
-
{ id: 'basic_info', message: 'Basic plan selected!' },
|
|
287
|
-
{ id: 'pro_info', message: 'Pro plan selected!' },
|
|
288
|
-
],
|
|
289
|
-
};
|
|
290
|
-
|
|
291
|
-
<ChatBot
|
|
292
|
-
flow={flow}
|
|
293
|
-
components={{ PlanSelector }} // register your components here
|
|
294
|
-
/>
|
|
295
|
-
```
|
|
296
|
-
|
|
297
|
-
### StepComponentProps
|
|
298
|
-
|
|
299
|
-
| Property | Type | Description |
|
|
300
|
-
|----------|------|-------------|
|
|
301
|
-
| `stepId` | `string` | The step ID that owns this component |
|
|
302
|
-
| `data` | `Record<string, unknown>` | All collected flow/form data |
|
|
303
|
-
| `onComplete` | `(result?: FlowActionResult) => void` | Call to complete the step and route to the next |
|
|
304
|
-
|
|
305
|
-
## Dynamic Routing
|
|
306
|
-
|
|
307
|
-
Use `asyncAction.routes` to map API result statuses to different steps:
|
|
308
|
-
|
|
309
|
-
```tsx
|
|
310
|
-
{
|
|
311
|
-
id: 'check_account',
|
|
312
|
-
message: 'Looking up your account...',
|
|
313
|
-
asyncAction: {
|
|
314
|
-
handler: 'check-account',
|
|
315
|
-
loadingMessage: '🔍 Searching...',
|
|
316
|
-
routes: {
|
|
317
|
-
admin: 'admin_panel', // result.status === 'admin'
|
|
318
|
-
vip: 'vip_welcome', // result.status === 'vip'
|
|
319
|
-
active: 'dashboard', // result.status === 'active'
|
|
320
|
-
not_found: 'register', // result.status === 'not_found'
|
|
321
|
-
},
|
|
322
|
-
},
|
|
323
|
-
}
|
|
324
|
-
```
|
|
325
|
-
|
|
326
|
-
The action handler returns the status that determines which route to take:
|
|
327
|
-
|
|
328
|
-
```ts
|
|
329
|
-
'check-account': async (data, ctx) => {
|
|
330
|
-
const user = await api.lookup(data.username);
|
|
331
|
-
if (!user) return { status: 'not_found' };
|
|
332
|
-
return { status: user.role, data: { userId: user.id } };
|
|
333
|
-
}
|
|
334
|
-
```
|
|
335
|
-
|
|
336
|
-
## Slash Commands
|
|
337
|
-
|
|
338
|
-
Users can type these commands in the chat input:
|
|
339
|
-
|
|
340
|
-
| Command | Description |
|
|
341
|
-
|---------|-------------|
|
|
342
|
-
| `/help` | Show available commands |
|
|
343
|
-
| `/back` | Go back to the previous step |
|
|
344
|
-
| `/cancel` | Same as /back — cancel current step |
|
|
345
|
-
| `/restart` | Restart the conversation from the beginning |
|
|
346
|
-
|
|
347
|
-
## Custom Header & Input
|
|
348
|
-
|
|
349
|
-
Use `renderHeader` and `renderInput` to replace the default header or input with your own components. Both receive a `ChatRenderContext` object and the default element:
|
|
350
|
-
|
|
351
|
-
```tsx
|
|
352
|
-
<ChatBot
|
|
353
|
-
flow={flow}
|
|
354
|
-
renderHeader={(ctx, defaultHeader) => (
|
|
355
|
-
<div style={{ padding: 16, background: '#333', color: '#fff' }}>
|
|
356
|
-
<h3>My Custom Header</h3>
|
|
357
|
-
<p>Step: {ctx.currentStepId ?? 'none'}</p>
|
|
358
|
-
<button onClick={ctx.restartSession}>Restart</button>
|
|
359
|
-
<button onClick={ctx.toggleChat}>Close</button>
|
|
360
|
-
</div>
|
|
361
|
-
)}
|
|
362
|
-
renderInput={(ctx, defaultInput) => {
|
|
363
|
-
// Use the default input but wrap it
|
|
364
|
-
return (
|
|
365
|
-
<div>
|
|
366
|
-
{defaultInput}
|
|
367
|
-
<small>Step: {ctx.currentStepId}</small>
|
|
368
|
-
</div>
|
|
369
|
-
);
|
|
370
|
-
}}
|
|
371
|
-
/>
|
|
372
|
-
```
|
|
373
|
-
|
|
374
|
-
### ChatRenderContext
|
|
375
|
-
|
|
376
|
-
| Property | Type | Description |
|
|
377
|
-
|----------|------|-------------|
|
|
378
|
-
| `currentStepId` | `string \| null` | Current flow step ID |
|
|
379
|
-
| `isOpen` | `boolean` | Whether the chat window is open |
|
|
380
|
-
| `messages` | `ChatMessage[]` | All messages |
|
|
381
|
-
| `collectedData` | `Record<string, unknown>` | Collected form/flow data |
|
|
382
|
-
| `toggleChat` | `() => void` | Open/close the chat |
|
|
383
|
-
| `restartSession` | `() => void` | Restart from beginning |
|
|
384
|
-
| `sendMessage` | `(text: string) => void` | Send a message programmatically |
|
|
385
|
-
|
|
386
|
-
## Theming
|
|
387
|
-
|
|
388
|
-
```tsx
|
|
389
|
-
<ChatBot
|
|
390
|
-
theme={{
|
|
391
|
-
primaryColor: '#6C5CE7',
|
|
392
|
-
headerBg: 'linear-gradient(135deg, #6C5CE7, #A29BFE)',
|
|
393
|
-
borderRadius: '20px',
|
|
394
|
-
mode: 'dark', // or 'light'
|
|
395
|
-
fontFamily: '"Inter", sans-serif',
|
|
396
|
-
windowWidth: '400px',
|
|
397
|
-
windowHeight: '600px',
|
|
398
|
-
}}
|
|
399
|
-
/>
|
|
400
|
-
```
|
|
401
|
-
|
|
402
|
-
All theme values are also exposed as CSS variables (`--cb-primary`, `--cb-header-bg`, etc.).
|
|
403
|
-
|
|
404
|
-
## Plugins
|
|
405
|
-
|
|
406
|
-
### Built-in Plugins
|
|
407
|
-
|
|
408
|
-
```tsx
|
|
409
|
-
import { analyticsPlugin, webhookPlugin, persistencePlugin } from '@enjoys/react-chatbot-plugin';
|
|
410
|
-
|
|
411
|
-
<ChatBot
|
|
412
|
-
plugins={[
|
|
413
|
-
analyticsPlugin({
|
|
414
|
-
onTrack: (event, data) => console.log(event, data),
|
|
415
|
-
}),
|
|
416
|
-
webhookPlugin({
|
|
417
|
-
url: '/api/chatbot-webhook',
|
|
418
|
-
events: ['message', 'submit'],
|
|
419
|
-
}),
|
|
420
|
-
persistencePlugin({
|
|
421
|
-
storageKey: 'my_chat',
|
|
422
|
-
storage: 'local', // or 'session'
|
|
423
|
-
}),
|
|
424
|
-
]}
|
|
425
|
-
/>
|
|
426
|
-
```
|
|
427
|
-
|
|
428
|
-
### Custom Plugin
|
|
429
|
-
|
|
430
|
-
```ts
|
|
431
|
-
import type { ChatPlugin } from '@enjoys/react-chatbot-plugin';
|
|
432
|
-
|
|
433
|
-
const myPlugin: ChatPlugin = {
|
|
434
|
-
name: 'my-plugin',
|
|
435
|
-
onInit(ctx) {
|
|
436
|
-
console.log('Chat initialized');
|
|
437
|
-
},
|
|
438
|
-
onMessage(message, ctx) {
|
|
439
|
-
console.log('Message:', message);
|
|
440
|
-
},
|
|
441
|
-
onSubmit(data, ctx) {
|
|
442
|
-
console.log('Form submitted:', data);
|
|
443
|
-
},
|
|
444
|
-
onDestroy(ctx) {
|
|
445
|
-
console.log('Chat destroyed');
|
|
446
|
-
},
|
|
447
|
-
};
|
|
448
|
-
```
|
|
449
|
-
|
|
450
|
-
### Plugin Context
|
|
451
|
-
|
|
452
|
-
| Method | Description |
|
|
453
|
-
|--------|-------------|
|
|
454
|
-
| `sendMessage(text)` | Send a user message |
|
|
455
|
-
| `addBotMessage(text)` | Add a bot message |
|
|
456
|
-
| `getMessages()` | Get all messages |
|
|
457
|
-
| `getData()` | Get collected data |
|
|
458
|
-
| `setData(key, value)` | Set data |
|
|
459
|
-
| `on(event, handler)` | Subscribe to events |
|
|
460
|
-
| `emit(event, ...args)` | Emit events |
|
|
461
|
-
|
|
462
|
-
## Forms
|
|
463
|
-
|
|
464
|
-
Forms can be used in flows or as a login screen:
|
|
465
|
-
|
|
466
|
-
```ts
|
|
467
|
-
const form: FormConfig = {
|
|
468
|
-
id: 'contact',
|
|
469
|
-
title: 'Contact Us',
|
|
470
|
-
description: 'Fill out the form below',
|
|
471
|
-
fields: [
|
|
472
|
-
{ name: 'name', type: 'text', label: 'Name', required: true },
|
|
473
|
-
{ name: 'email', type: 'email', label: 'Email', required: true,
|
|
474
|
-
validation: { pattern: '^[^@]+@[^@]+\\.[^@]+$', message: 'Invalid email' } },
|
|
475
|
-
{ name: 'priority', type: 'select', label: 'Priority', options: [
|
|
476
|
-
{ label: 'Low', value: 'low' },
|
|
477
|
-
{ label: 'High', value: 'high' },
|
|
478
|
-
]},
|
|
479
|
-
{ name: 'message', type: 'textarea', label: 'Message' },
|
|
480
|
-
{ name: 'file', type: 'file', label: 'Attachment', accept: 'image/*,.pdf' },
|
|
481
|
-
],
|
|
482
|
-
submitLabel: 'Send',
|
|
483
|
-
};
|
|
484
|
-
```
|
|
485
|
-
|
|
486
|
-
**Supported field types:** `text`, `email`, `password`, `number`, `tel`, `url`, `textarea`, `select`, `multiselect`, `radio`, `checkbox`, `file`, `date`, `time`, `hidden`
|
|
487
|
-
|
|
488
|
-
## Callbacks
|
|
489
|
-
|
|
490
|
-
```tsx
|
|
491
|
-
<ChatBot
|
|
492
|
-
callbacks={{
|
|
493
|
-
onOpen: () => {},
|
|
494
|
-
onClose: () => {},
|
|
495
|
-
onMessageSend: (msg) => {},
|
|
496
|
-
onMessageReceive: (msg) => {},
|
|
497
|
-
onSubmit: (data) => {},
|
|
498
|
-
onLogin: (data) => {},
|
|
499
|
-
onFormSubmit: (formId, data) => {},
|
|
500
|
-
onQuickReply: (value, label) => {},
|
|
501
|
-
onFileUpload: (files) => {},
|
|
502
|
-
onFlowEnd: (collectedData) => {},
|
|
503
|
-
onError: (error) => {},
|
|
504
|
-
onEvent: (event, payload) => {},
|
|
505
|
-
}}
|
|
506
|
-
/>
|
|
507
|
-
```
|
|
508
|
-
|
|
509
|
-
## File Upload
|
|
510
|
-
|
|
511
|
-
```tsx
|
|
512
|
-
<ChatBot
|
|
513
|
-
fileUpload={{
|
|
514
|
-
enabled: true,
|
|
515
|
-
accept: 'image/*,.pdf,.doc,.docx',
|
|
516
|
-
multiple: true,
|
|
517
|
-
maxSize: 5 * 1024 * 1024, // 5MB
|
|
518
|
-
maxFiles: 3,
|
|
519
|
-
}}
|
|
520
|
-
/>
|
|
521
|
-
```
|
|
522
|
-
|
|
523
157
|
## Exported Components
|
|
524
158
|
|
|
525
159
|
All internal components are exported for advanced use cases:
|
|
526
160
|
|
|
527
|
-
`ChatBot`, `ChatHeader`, `ChatInput`, `ChatWindow`, `Launcher`, `MessageBubble`, `MessageList`, `QuickReplies`, `TypingIndicator`, `WelcomeScreen`, `LoginScreen`, `Branding`, `EmojiPicker`, `FileUploadButton`, `FilePreviewList`, `DynamicForm
|
|
161
|
+
**UI:** `ChatBot`, `ChatHeader`, `ChatInput`, `ChatWindow`, `Launcher`, `MessageBubble`, `MessageList`, `QuickReplies`, `TypingIndicator`, `WelcomeScreen`, `LoginScreen`, `Branding`, `EmojiPicker`, `FileUploadButton`, `FilePreviewList`, `DynamicForm`
|
|
162
|
+
|
|
163
|
+
**Forms:** `TextField`, `SelectField`, `RadioField`, `CheckboxField`, `FileUploadField`
|
|
528
164
|
|
|
529
165
|
**Icons:** `SendIcon`, `ChatBubbleIcon`, `CloseIcon`, `MinimizeIcon`, `EmojiIcon`, `AttachmentIcon`, `FileIcon`, `ImageIcon`, `RemoveIcon`, `RestartIcon`
|
|
530
166
|
|
|
@@ -532,19 +168,31 @@ All internal components are exported for advanced use cases:
|
|
|
532
168
|
|
|
533
169
|
**Theme utilities:** `resolveTheme`, `buildStyles`, `buildCSSVariables`
|
|
534
170
|
|
|
171
|
+
**Built-in plugins:** `analyticsPlugin`, `webhookPlugin`, `persistencePlugin`
|
|
172
|
+
|
|
535
173
|
## Development
|
|
536
174
|
|
|
537
175
|
```bash
|
|
538
176
|
# Install dependencies
|
|
539
177
|
bun install
|
|
540
178
|
|
|
541
|
-
# Run demo
|
|
179
|
+
# Run demo (14 interactive demos)
|
|
542
180
|
bun run dev
|
|
543
181
|
|
|
544
182
|
# Build library
|
|
545
183
|
bun run build
|
|
546
184
|
```
|
|
547
185
|
|
|
186
|
+
## Contributing
|
|
187
|
+
|
|
188
|
+
Contributions are welcome! Please open an issue or submit a pull request.
|
|
189
|
+
|
|
190
|
+
1. Fork the repository
|
|
191
|
+
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
|
|
192
|
+
3. Commit your changes (`git commit -m 'Add amazing feature'`)
|
|
193
|
+
4. Push to the branch (`git push origin feature/amazing-feature`)
|
|
194
|
+
5. Open a Pull Request
|
|
195
|
+
|
|
548
196
|
## License
|
|
549
197
|
|
|
550
|
-
MIT
|
|
198
|
+
MIT © [Enjoys](https://github.com/enjoys-in)
|