interview-widget 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/README.md +281 -0
- package/dist/ChatWidget.d.ts +5 -0
- package/dist/Message.d.ts +10 -0
- package/dist/chat-widget.css +1 -0
- package/dist/chat-widget.es.js +189 -0
- package/dist/chat-widget.umd.js +9 -0
- package/dist/dev.d.ts +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/types.d.ts +25 -0
- package/package.json +51 -0
package/README.md
ADDED
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
# Chat Widget
|
|
2
|
+
|
|
3
|
+
A simple, customizable React chat widget that can be easily embedded into any website or React application via CDN.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- 🎨 **Customizable themes** (Light/Dark)
|
|
8
|
+
- 📱 **Responsive design** with mobile support
|
|
9
|
+
- 🔧 **Flexible positioning** (inline, fixed bottom-right/left)
|
|
10
|
+
- ⚡ **TypeScript support** with full type definitions
|
|
11
|
+
- 🎯 **CDN-ready** for easy integration into any website
|
|
12
|
+
- 🔄 **Auto-reply functionality** for standalone use
|
|
13
|
+
- 💬 **Controlled/uncontrolled** component modes
|
|
14
|
+
- 🎪 **Tailwind CSS** with prefixed classes to avoid conflicts
|
|
15
|
+
- ✨ **Smooth animations** and modern UI
|
|
16
|
+
|
|
17
|
+
## Quick Start
|
|
18
|
+
|
|
19
|
+
### CDN Integration (Any Website)
|
|
20
|
+
|
|
21
|
+
Add these scripts to your HTML:
|
|
22
|
+
|
|
23
|
+
```html
|
|
24
|
+
<!-- Load React and ReactDOM from CDN -->
|
|
25
|
+
<script crossorigin src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
|
|
26
|
+
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
|
|
27
|
+
|
|
28
|
+
<!-- Load the chat widget CSS -->
|
|
29
|
+
<link rel="stylesheet" href="https://your-cdn.com/chat-widget.css">
|
|
30
|
+
|
|
31
|
+
<!-- Load the chat widget JavaScript -->
|
|
32
|
+
<script src="https://your-cdn.com/chat-widget.umd.js"></script>
|
|
33
|
+
|
|
34
|
+
<script>
|
|
35
|
+
document.addEventListener('DOMContentLoaded', function() {
|
|
36
|
+
const { ChatWidget } = window.ChatWidget;
|
|
37
|
+
|
|
38
|
+
ReactDOM.render(
|
|
39
|
+
React.createElement(ChatWidget, {
|
|
40
|
+
title: 'Customer Support',
|
|
41
|
+
placeholder: 'How can we help you?',
|
|
42
|
+
position: 'bottom-right'
|
|
43
|
+
}),
|
|
44
|
+
document.getElementById('chat-widget-container')
|
|
45
|
+
);
|
|
46
|
+
});
|
|
47
|
+
</script>
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### React Application Integration
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
npm install chat-widget
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
```tsx
|
|
57
|
+
import React from 'react';
|
|
58
|
+
import { ChatWidget, Message } from 'chat-widget';
|
|
59
|
+
|
|
60
|
+
function App() {
|
|
61
|
+
const [messages, setMessages] = useState<Message[]>([]);
|
|
62
|
+
|
|
63
|
+
const handleSendMessage = (messageText: string) => {
|
|
64
|
+
// Handle sending message to your backend
|
|
65
|
+
console.log('User sent:', messageText);
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
return (
|
|
69
|
+
<div>
|
|
70
|
+
<ChatWidget
|
|
71
|
+
title="Support Chat"
|
|
72
|
+
messages={messages}
|
|
73
|
+
onSendMessage={handleSendMessage}
|
|
74
|
+
position="bottom-right"
|
|
75
|
+
/>
|
|
76
|
+
</div>
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## API Reference
|
|
82
|
+
|
|
83
|
+
### ChatWidget Props
|
|
84
|
+
|
|
85
|
+
| Prop | Type | Default | Description |
|
|
86
|
+
|------|------|---------|-------------|
|
|
87
|
+
| `title` | `string` | `"Chat Support"` | Title displayed in the chat header |
|
|
88
|
+
| `placeholder` | `string` | `"Type your message..."` | Input field placeholder text |
|
|
89
|
+
| `onSendMessage` | `(message: string) => void` | `undefined` | Callback when user sends a message |
|
|
90
|
+
| `messages` | `Message[]` | `[]` | Array of messages for controlled mode |
|
|
91
|
+
| `className` | `string` | `""` | Additional CSS classes |
|
|
92
|
+
| `botName` | `string` | `"Support Bot"` | Name displayed for bot messages |
|
|
93
|
+
| `userName` | `string` | `"You"` | Name displayed for user messages |
|
|
94
|
+
| `height` | `string` | `"400px"` | Height of the chat widget |
|
|
95
|
+
| `width` | `string` | `"350px"` | Width of the chat widget |
|
|
96
|
+
| `position` | `'bottom-right' \| 'bottom-left' \| 'inline'` | `"inline"` | Widget positioning |
|
|
97
|
+
| `theme` | `'light' \| 'dark'` | `"light"` | Color theme |
|
|
98
|
+
|
|
99
|
+
### Message Interface
|
|
100
|
+
|
|
101
|
+
```typescript
|
|
102
|
+
interface Message {
|
|
103
|
+
id: string;
|
|
104
|
+
text: string;
|
|
105
|
+
sender: 'user' | 'bot';
|
|
106
|
+
timestamp: Date;
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## Usage Examples
|
|
111
|
+
|
|
112
|
+
### Standalone Widget (Auto-reply)
|
|
113
|
+
|
|
114
|
+
```tsx
|
|
115
|
+
<ChatWidget
|
|
116
|
+
title="AI Assistant"
|
|
117
|
+
placeholder="Ask me anything..."
|
|
118
|
+
botName="AI Helper"
|
|
119
|
+
userName="Visitor"
|
|
120
|
+
/>
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Controlled Widget
|
|
124
|
+
|
|
125
|
+
```tsx
|
|
126
|
+
const [messages, setMessages] = useState<Message[]>([]);
|
|
127
|
+
|
|
128
|
+
const handleMessage = async (text: string) => {
|
|
129
|
+
// Add user message
|
|
130
|
+
const userMessage = {
|
|
131
|
+
id: Date.now().toString(),
|
|
132
|
+
text,
|
|
133
|
+
sender: 'user' as const,
|
|
134
|
+
timestamp: new Date()
|
|
135
|
+
};
|
|
136
|
+
setMessages(prev => [...prev, userMessage]);
|
|
137
|
+
|
|
138
|
+
// Get bot response from your API
|
|
139
|
+
const response = await fetch('/api/chat', {
|
|
140
|
+
method: 'POST',
|
|
141
|
+
body: JSON.stringify({ message: text })
|
|
142
|
+
});
|
|
143
|
+
const data = await response.json();
|
|
144
|
+
|
|
145
|
+
// Add bot response
|
|
146
|
+
const botMessage = {
|
|
147
|
+
id: (Date.now() + 1).toString(),
|
|
148
|
+
text: data.reply,
|
|
149
|
+
sender: 'bot' as const,
|
|
150
|
+
timestamp: new Date()
|
|
151
|
+
};
|
|
152
|
+
setMessages(prev => [...prev, botMessage]);
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
<ChatWidget
|
|
156
|
+
messages={messages}
|
|
157
|
+
onSendMessage={handleMessage}
|
|
158
|
+
/>
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Fixed Position Widget
|
|
162
|
+
|
|
163
|
+
```tsx
|
|
164
|
+
<ChatWidget
|
|
165
|
+
title="Help & Support"
|
|
166
|
+
position="bottom-right"
|
|
167
|
+
height="500px"
|
|
168
|
+
width="300px"
|
|
169
|
+
/>
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### Dark Theme
|
|
173
|
+
|
|
174
|
+
```tsx
|
|
175
|
+
<ChatWidget
|
|
176
|
+
theme="dark"
|
|
177
|
+
title="Night Support"
|
|
178
|
+
botName="Night Owl Bot"
|
|
179
|
+
/>
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
## Development
|
|
183
|
+
|
|
184
|
+
### Setup
|
|
185
|
+
|
|
186
|
+
```bash
|
|
187
|
+
git clone https://github.com/your-username/chat-widget.git
|
|
188
|
+
cd chat-widget
|
|
189
|
+
npm install
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### Development Server
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
npm run dev
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
Open http://localhost:5173 to see the development examples.
|
|
199
|
+
|
|
200
|
+
### Build
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
npm run build
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
This creates:
|
|
207
|
+
- `dist/chat-widget.umd.js` - UMD build for CDN
|
|
208
|
+
- `dist/chat-widget.es.js` - ES modules build
|
|
209
|
+
- `dist/chat-widget.css` - Styles
|
|
210
|
+
- `dist/index.d.ts` - TypeScript definitions
|
|
211
|
+
|
|
212
|
+
### Testing Examples
|
|
213
|
+
|
|
214
|
+
After building, you can test the CDN integration by opening `examples/cdn-example.html` in your browser.
|
|
215
|
+
|
|
216
|
+
## Customization
|
|
217
|
+
|
|
218
|
+
### Custom Styles
|
|
219
|
+
|
|
220
|
+
The widget uses Tailwind CSS with the `cw-` prefix to avoid conflicts. You can override styles:
|
|
221
|
+
|
|
222
|
+
```css
|
|
223
|
+
.chat-widget-container {
|
|
224
|
+
/* Your custom styles */
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
.cw-bg-primary-500 {
|
|
228
|
+
background-color: your-brand-color !important;
|
|
229
|
+
}
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
### API Integration
|
|
233
|
+
|
|
234
|
+
For production use, implement your chat API:
|
|
235
|
+
|
|
236
|
+
```tsx
|
|
237
|
+
const handleSendMessage = async (message: string) => {
|
|
238
|
+
try {
|
|
239
|
+
const response = await fetch('/api/chat', {
|
|
240
|
+
method: 'POST',
|
|
241
|
+
headers: { 'Content-Type': 'application/json' },
|
|
242
|
+
body: JSON.stringify({
|
|
243
|
+
message,
|
|
244
|
+
sessionId: 'user-session-id',
|
|
245
|
+
timestamp: new Date().toISOString()
|
|
246
|
+
})
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
const data = await response.json();
|
|
250
|
+
// Handle response...
|
|
251
|
+
} catch (error) {
|
|
252
|
+
// Handle error...
|
|
253
|
+
}
|
|
254
|
+
};
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
## Browser Support
|
|
258
|
+
|
|
259
|
+
- Chrome (latest)
|
|
260
|
+
- Firefox (latest)
|
|
261
|
+
- Safari (latest)
|
|
262
|
+
- Edge (latest)
|
|
263
|
+
- IE 11+ (with polyfills)
|
|
264
|
+
|
|
265
|
+
## License
|
|
266
|
+
|
|
267
|
+
MIT License - see LICENSE file for details.
|
|
268
|
+
|
|
269
|
+
## Contributing
|
|
270
|
+
|
|
271
|
+
1. Fork the repository
|
|
272
|
+
2. Create a feature branch
|
|
273
|
+
3. Make your changes
|
|
274
|
+
4. Add tests if applicable
|
|
275
|
+
5. Submit a pull request
|
|
276
|
+
|
|
277
|
+
## Support
|
|
278
|
+
|
|
279
|
+
- 📧 Email: support@yourcompany.com
|
|
280
|
+
- 🐛 Issues: [GitHub Issues](https://github.com/your-username/chat-widget/issues)
|
|
281
|
+
- 📖 Docs: [Documentation](https://your-docs-site.com)
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
import { Message as MessageType } from './types';
|
|
3
|
+
|
|
4
|
+
interface MessageProps {
|
|
5
|
+
message: MessageType;
|
|
6
|
+
botName: string;
|
|
7
|
+
userName: string;
|
|
8
|
+
}
|
|
9
|
+
declare const Message: React.FC<MessageProps>;
|
|
10
|
+
export default Message;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
*,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:Inter,system-ui,sans-serif;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.cw-mx-auto{margin-left:auto!important;margin-right:auto!important}.cw-mb-1{margin-bottom:.25rem!important}.cw-mb-4{margin-bottom:1rem!important}.cw-mb-8{margin-bottom:2rem!important}.cw-ml-2{margin-left:.5rem!important}.cw-mt-8{margin-top:2rem!important}.cw-flex{display:flex!important}.cw-grid{display:grid!important}.cw-min-h-screen{min-height:100vh!important}.cw-w-full{width:100%!important}.cw-max-w-4xl{max-width:56rem!important}.cw-max-w-xs{max-width:20rem!important}.cw-flex-1{flex:1 1 0%!important}.cw-cursor-default{cursor:default!important}.cw-cursor-pointer{cursor:pointer!important}.cw-grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))!important}.cw-grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))!important}.cw-flex-col{flex-direction:column!important}.cw-items-center{align-items:center!important}.cw-justify-start{justify-content:flex-start!important}.cw-justify-end{justify-content:flex-end!important}.cw-justify-between{justify-content:space-between!important}.cw-gap-8{gap:2rem!important}.cw-space-x-2>:not([hidden])~:not([hidden]){--tw-space-x-reverse: 0 !important;margin-right:calc(.5rem * var(--tw-space-x-reverse))!important;margin-left:calc(.5rem * calc(1 - var(--tw-space-x-reverse)))!important}.cw-overflow-y-auto{overflow-y:auto!important}.cw-break-words{overflow-wrap:break-word!important}.cw-rounded{border-radius:.25rem!important}.cw-rounded-lg{border-radius:.5rem!important}.cw-rounded-md{border-radius:.375rem!important}.cw-rounded-t-lg{border-top-left-radius:.5rem!important;border-top-right-radius:.5rem!important}.cw-border{border-width:1px!important}.cw-border-b{border-bottom-width:1px!important}.cw-border-t{border-top-width:1px!important}.cw-border-gray-200{--tw-border-opacity: 1 !important;border-color:rgb(229 231 235 / var(--tw-border-opacity, 1))!important}.cw-border-gray-300{--tw-border-opacity: 1 !important;border-color:rgb(209 213 219 / var(--tw-border-opacity, 1))!important}.cw-border-gray-600{--tw-border-opacity: 1 !important;border-color:rgb(75 85 99 / var(--tw-border-opacity, 1))!important}.cw-bg-blue-500{--tw-bg-opacity: 1 !important;background-color:rgb(59 130 246 / var(--tw-bg-opacity, 1))!important}.cw-bg-blue-600{--tw-bg-opacity: 1 !important;background-color:rgb(37 99 235 / var(--tw-bg-opacity, 1))!important}.cw-bg-gray-200{--tw-bg-opacity: 1 !important;background-color:rgb(229 231 235 / var(--tw-bg-opacity, 1))!important}.cw-bg-gray-50{--tw-bg-opacity: 1 !important;background-color:rgb(249 250 251 / var(--tw-bg-opacity, 1))!important}.cw-bg-gray-700{--tw-bg-opacity: 1 !important;background-color:rgb(55 65 81 / var(--tw-bg-opacity, 1))!important}.cw-bg-gray-800{--tw-bg-opacity: 1 !important;background-color:rgb(31 41 55 / var(--tw-bg-opacity, 1))!important}.cw-bg-primary-500{--tw-bg-opacity: 1 !important;background-color:rgb(59 130 246 / var(--tw-bg-opacity, 1))!important}.cw-bg-white{--tw-bg-opacity: 1 !important;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1))!important}.cw-p-1{padding:.25rem!important}.cw-p-4{padding:1rem!important}.cw-p-8{padding:2rem!important}.cw-px-3{padding-left:.75rem!important;padding-right:.75rem!important}.cw-px-4{padding-left:1rem!important;padding-right:1rem!important}.cw-py-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.cw-text-center{text-align:center!important}.cw-text-2xl{font-size:1.5rem!important;line-height:2rem!important}.cw-text-lg{font-size:1.125rem!important;line-height:1.75rem!important}.cw-text-sm{font-size:.875rem!important;line-height:1.25rem!important}.cw-text-xl{font-size:1.25rem!important;line-height:1.75rem!important}.cw-text-xs{font-size:.75rem!important;line-height:1rem!important}.cw-font-bold{font-weight:700!important}.cw-font-medium{font-weight:500!important}.cw-font-semibold{font-weight:600!important}.cw-text-gray-400{--tw-text-opacity: 1 !important;color:rgb(156 163 175 / var(--tw-text-opacity, 1))!important}.cw-text-gray-500{--tw-text-opacity: 1 !important;color:rgb(107 114 128 / var(--tw-text-opacity, 1))!important}.cw-text-gray-600{--tw-text-opacity: 1 !important;color:rgb(75 85 99 / var(--tw-text-opacity, 1))!important}.cw-text-gray-800{--tw-text-opacity: 1 !important;color:rgb(31 41 55 / var(--tw-text-opacity, 1))!important}.cw-text-white{--tw-text-opacity: 1 !important;color:rgb(255 255 255 / var(--tw-text-opacity, 1))!important}.cw-placeholder-gray-400::-moz-placeholder{--tw-placeholder-opacity: 1 !important;color:rgb(156 163 175 / var(--tw-placeholder-opacity, 1))!important}.cw-placeholder-gray-400::placeholder{--tw-placeholder-opacity: 1 !important;color:rgb(156 163 175 / var(--tw-placeholder-opacity, 1))!important}.cw-opacity-70{opacity:.7!important}.cw-shadow-lg{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1) !important;--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color) !important;box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)!important}.cw-transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke!important;transition-timing-function:cubic-bezier(.4,0,.2,1)!important;transition-duration:.15s!important}:root{--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-opacity: .5}.chat-widget-container{font-family:Inter,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif}.chat-messages::-webkit-scrollbar{width:6px}.chat-messages::-webkit-scrollbar-track{background:#f1f1f1}.chat-messages::-webkit-scrollbar-thumb{background:#c1c1c1;border-radius:3px}.chat-messages::-webkit-scrollbar-thumb:hover{background:#a8a8a8}@keyframes slideIn{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}.message-animation{animation:slideIn .3s ease-out}.cw-hover\:bg-primary-600:hover{background-color:#2563eb!important}.cw-focus\:outline-none:focus{outline:2px solid transparent!important;outline-offset:2px!important}.cw-focus\:ring-2:focus{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color) !important;--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color) !important;box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)!important}.cw-focus\:ring-primary-500:focus{--tw-ring-opacity: 1 !important;--tw-ring-color: rgb(59 130 246 / var(--tw-ring-opacity, 1)) !important}.cw-disabled\:opacity-50:disabled{opacity:.5!important}.cw-disabled\:cursor-not-allowed:disabled{cursor:not-allowed!important}@media (min-width: 1024px){.cw-lg\:max-w-md{max-width:28rem!important}}@media (min-width: 768px){.cw-md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))!important}}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import W, { useState as h, useRef as N, useEffect as H } from "react";
|
|
2
|
+
var _ = { exports: {} }, p = {};
|
|
3
|
+
/**
|
|
4
|
+
* @license React
|
|
5
|
+
* react-jsx-runtime.production.min.js
|
|
6
|
+
*
|
|
7
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
8
|
+
*
|
|
9
|
+
* This source code is licensed under the MIT license found in the
|
|
10
|
+
* LICENSE file in the root directory of this source tree.
|
|
11
|
+
*/
|
|
12
|
+
var P = W, B = Symbol.for("react.element"), M = Symbol.for("react.fragment"), q = Object.prototype.hasOwnProperty, z = P.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner, F = { key: !0, ref: !0, __self: !0, __source: !0 };
|
|
13
|
+
function k(s, c, n) {
|
|
14
|
+
var t, i = {}, a = null, u = null;
|
|
15
|
+
n !== void 0 && (a = "" + n), c.key !== void 0 && (a = "" + c.key), c.ref !== void 0 && (u = c.ref);
|
|
16
|
+
for (t in c)
|
|
17
|
+
q.call(c, t) && !F.hasOwnProperty(t) && (i[t] = c[t]);
|
|
18
|
+
if (s && s.defaultProps)
|
|
19
|
+
for (t in c = s.defaultProps, c)
|
|
20
|
+
i[t] === void 0 && (i[t] = c[t]);
|
|
21
|
+
return { $$typeof: B, type: s, key: a, ref: u, props: i, _owner: z.current };
|
|
22
|
+
}
|
|
23
|
+
p.Fragment = M;
|
|
24
|
+
p.jsx = k;
|
|
25
|
+
p.jsxs = k;
|
|
26
|
+
_.exports = p;
|
|
27
|
+
var e = _.exports;
|
|
28
|
+
const I = ({ message: s, botName: c, userName: n }) => {
|
|
29
|
+
const t = s.sender === "bot", i = (a) => a.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
|
|
30
|
+
return /* @__PURE__ */ e.jsx("div", { className: `cw-flex cw-mb-4 message-animation ${t ? "cw-justify-start" : "cw-justify-end"}`, children: /* @__PURE__ */ e.jsxs("div", { className: `cw-max-w-xs cw-lg:max-w-md cw-px-4 cw-py-2 cw-rounded-lg cw-break-words ${t ? "cw-bg-gray-200 cw-text-gray-800" : "cw-bg-primary-500 cw-text-white"}`, children: [
|
|
31
|
+
/* @__PURE__ */ e.jsxs("div", { className: "cw-flex cw-items-center cw-mb-1", children: [
|
|
32
|
+
/* @__PURE__ */ e.jsx("span", { className: "cw-text-xs cw-font-semibold", children: t ? c : n }),
|
|
33
|
+
/* @__PURE__ */ e.jsx("span", { className: "cw-text-xs cw-opacity-70 cw-ml-2", children: i(s.timestamp) })
|
|
34
|
+
] }),
|
|
35
|
+
/* @__PURE__ */ e.jsx("div", { className: "cw-text-sm", children: s.text })
|
|
36
|
+
] }) });
|
|
37
|
+
}, K = ({
|
|
38
|
+
title: s = "Chat Support",
|
|
39
|
+
placeholder: c = "Type your message...",
|
|
40
|
+
onSendMessage: n,
|
|
41
|
+
messages: t = [],
|
|
42
|
+
className: i = "",
|
|
43
|
+
botName: a = "Support Bot",
|
|
44
|
+
userName: u = "You",
|
|
45
|
+
height: R = "400px",
|
|
46
|
+
width: $ = "350px",
|
|
47
|
+
position: y = "inline",
|
|
48
|
+
theme: l = "light"
|
|
49
|
+
}) => {
|
|
50
|
+
const [S, g] = h([]), [w, f] = h(""), [m, T] = h(!1), b = N(null), v = N(null), x = t.length > 0 ? t : S, C = (r) => {
|
|
51
|
+
const d = [
|
|
52
|
+
"Thanks for your message! How can I help you today?",
|
|
53
|
+
"I understand your concern. Let me assist you with that.",
|
|
54
|
+
"That's a great question! Here's what I can tell you...",
|
|
55
|
+
"I'm here to help! Can you provide more details?",
|
|
56
|
+
"Thank you for reaching out. I'll do my best to assist you."
|
|
57
|
+
], o = r.toLowerCase();
|
|
58
|
+
return o.includes("hello") || o.includes("hi") ? "Hello! Welcome to our support chat. How can I help you today?" : o.includes("help") ? "I'm here to help! What do you need assistance with?" : o.includes("price") || o.includes("cost") ? "I can help you with pricing information. What specific product or service are you interested in?" : d[Math.floor(Math.random() * d.length)];
|
|
59
|
+
}, E = () => {
|
|
60
|
+
var r;
|
|
61
|
+
(r = b.current) == null || r.scrollIntoView({ behavior: "smooth" });
|
|
62
|
+
};
|
|
63
|
+
H(() => {
|
|
64
|
+
E();
|
|
65
|
+
}, [x]);
|
|
66
|
+
const j = () => {
|
|
67
|
+
var d;
|
|
68
|
+
if (!w.trim())
|
|
69
|
+
return;
|
|
70
|
+
const r = {
|
|
71
|
+
id: Date.now().toString(),
|
|
72
|
+
text: w.trim(),
|
|
73
|
+
sender: "user",
|
|
74
|
+
timestamp: /* @__PURE__ */ new Date()
|
|
75
|
+
};
|
|
76
|
+
t.length > 0 ? n == null || n(w.trim()) : (g((o) => [...o, r]), setTimeout(() => {
|
|
77
|
+
const o = {
|
|
78
|
+
id: (Date.now() + 1).toString(),
|
|
79
|
+
text: C(w.trim()),
|
|
80
|
+
sender: "bot",
|
|
81
|
+
timestamp: /* @__PURE__ */ new Date()
|
|
82
|
+
};
|
|
83
|
+
g((L) => [...L, o]);
|
|
84
|
+
}, 1e3)), f(""), (d = v.current) == null || d.focus();
|
|
85
|
+
}, D = (r) => {
|
|
86
|
+
r.key === "Enter" && !r.shiftKey && (r.preventDefault(), j());
|
|
87
|
+
}, O = {
|
|
88
|
+
height: m ? "auto" : R,
|
|
89
|
+
width: $,
|
|
90
|
+
...y !== "inline" && {
|
|
91
|
+
position: "fixed",
|
|
92
|
+
bottom: "20px",
|
|
93
|
+
[y === "bottom-right" ? "right" : "left"]: "20px",
|
|
94
|
+
zIndex: 1e3
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
return /* @__PURE__ */ e.jsxs(
|
|
98
|
+
"div",
|
|
99
|
+
{
|
|
100
|
+
className: `chat-widget-container cw-bg-white cw-border cw-border-gray-300 cw-rounded-lg cw-shadow-lg cw-flex cw-flex-col ${l === "dark" ? "cw-bg-gray-800 cw-border-gray-600" : ""} ${i}`,
|
|
101
|
+
style: O,
|
|
102
|
+
children: [
|
|
103
|
+
/* @__PURE__ */ e.jsxs(
|
|
104
|
+
"div",
|
|
105
|
+
{
|
|
106
|
+
className: `cw-flex cw-items-center cw-justify-between cw-p-4 cw-border-b cw-bg-primary-500 cw-text-white cw-rounded-t-lg ${l === "dark" ? "cw-border-gray-600" : "cw-border-gray-200"}`,
|
|
107
|
+
children: [
|
|
108
|
+
/* @__PURE__ */ e.jsx("h3", { className: "cw-font-semibold cw-text-sm", children: s }),
|
|
109
|
+
y !== "inline" && /* @__PURE__ */ e.jsx(
|
|
110
|
+
"button",
|
|
111
|
+
{
|
|
112
|
+
onClick: () => T(!m),
|
|
113
|
+
className: "cw-text-white cw-hover:bg-primary-600 cw-rounded cw-p-1 cw-transition-colors",
|
|
114
|
+
children: m ? "▲" : "▼"
|
|
115
|
+
}
|
|
116
|
+
)
|
|
117
|
+
]
|
|
118
|
+
}
|
|
119
|
+
),
|
|
120
|
+
!m && /* @__PURE__ */ e.jsxs(e.Fragment, { children: [
|
|
121
|
+
/* @__PURE__ */ e.jsxs(
|
|
122
|
+
"div",
|
|
123
|
+
{
|
|
124
|
+
className: `cw-flex-1 cw-overflow-y-auto cw-p-4 chat-messages ${l === "dark" ? "cw-bg-gray-700" : "cw-bg-gray-50"}`,
|
|
125
|
+
style: { maxHeight: "calc(100% - 120px)" },
|
|
126
|
+
children: [
|
|
127
|
+
x.length === 0 && /* @__PURE__ */ e.jsx(
|
|
128
|
+
"div",
|
|
129
|
+
{
|
|
130
|
+
className: `cw-text-center cw-text-gray-500 cw-text-sm cw-mt-8 ${l === "dark" ? "cw-text-gray-400" : ""}`,
|
|
131
|
+
children: "Start a conversation by typing a message below."
|
|
132
|
+
}
|
|
133
|
+
),
|
|
134
|
+
x.map((r) => /* @__PURE__ */ e.jsx(
|
|
135
|
+
I,
|
|
136
|
+
{
|
|
137
|
+
message: r,
|
|
138
|
+
botName: a,
|
|
139
|
+
userName: u
|
|
140
|
+
},
|
|
141
|
+
r.id
|
|
142
|
+
)),
|
|
143
|
+
/* @__PURE__ */ e.jsx("div", { ref: b })
|
|
144
|
+
]
|
|
145
|
+
}
|
|
146
|
+
),
|
|
147
|
+
/* @__PURE__ */ e.jsx(
|
|
148
|
+
"div",
|
|
149
|
+
{
|
|
150
|
+
className: `cw-p-4 cw-border-t ${l === "dark" ? "cw-border-gray-600 cw-bg-gray-800" : "cw-border-gray-200"}`,
|
|
151
|
+
children: /* @__PURE__ */ e.jsxs("div", { className: "cw-flex cw-space-x-2 ", children: [
|
|
152
|
+
/* @__PURE__ */ e.jsx(
|
|
153
|
+
"input",
|
|
154
|
+
{
|
|
155
|
+
ref: v,
|
|
156
|
+
type: "text",
|
|
157
|
+
value: w,
|
|
158
|
+
onChange: (r) => f(r.target.value),
|
|
159
|
+
onKeyDown: D,
|
|
160
|
+
placeholder: c,
|
|
161
|
+
className: ` cw-w-full cw-flex-1 cw-px-3 cw-py-2 cw-border cw-rounded-md cw-text-sm cw-focus:outline-none cw-focus:ring-2 cw-focus:ring-primary-500 ${l === "dark" ? "cw-bg-gray-700 cw-border-gray-600 cw-text-white cw-placeholder-gray-400" : "cw-bg-white cw-border-gray-300"}`
|
|
162
|
+
}
|
|
163
|
+
),
|
|
164
|
+
/* @__PURE__ */ e.jsx(
|
|
165
|
+
"button",
|
|
166
|
+
{
|
|
167
|
+
onClick: j,
|
|
168
|
+
disabled: !w.trim(),
|
|
169
|
+
className: "cw-bg-primary-500 cw-text-white cw-px-4 cw-py-2 cw-rounded-md cw-text-sm cw-font-medium cw-hover:bg-primary-600 cw-disabled:opacity-50 cw-disabled:cursor-not-allowed cw-transition-colors",
|
|
170
|
+
children: "Send"
|
|
171
|
+
}
|
|
172
|
+
)
|
|
173
|
+
] })
|
|
174
|
+
}
|
|
175
|
+
)
|
|
176
|
+
] })
|
|
177
|
+
]
|
|
178
|
+
}
|
|
179
|
+
);
|
|
180
|
+
};
|
|
181
|
+
typeof window < "u" && (window.ChatWidget = {
|
|
182
|
+
ChatWidget: K,
|
|
183
|
+
Message: I
|
|
184
|
+
});
|
|
185
|
+
export {
|
|
186
|
+
K as ChatWidget,
|
|
187
|
+
I as Message,
|
|
188
|
+
K as default
|
|
189
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
(function(n,c){typeof exports=="object"&&typeof module<"u"?c(exports,require("react")):typeof define=="function"&&define.amd?define(["exports","react"],c):(n=typeof globalThis<"u"?globalThis:n||self,c(n.ChatWidget={},n.React))})(this,function(n,c){"use strict";const V="";var v={exports:{}},p={};/**
|
|
2
|
+
* @license React
|
|
3
|
+
* react-jsx-runtime.production.min.js
|
|
4
|
+
*
|
|
5
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
6
|
+
*
|
|
7
|
+
* This source code is licensed under the MIT license found in the
|
|
8
|
+
* LICENSE file in the root directory of this source tree.
|
|
9
|
+
*/var S=c,T=Symbol.for("react.element"),C=Symbol.for("react.fragment"),E=Object.prototype.hasOwnProperty,O=S.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,D={key:!0,ref:!0,__self:!0,__source:!0};function j(o,s,a){var t,l={},d=null,f=null;a!==void 0&&(d=""+a),s.key!==void 0&&(d=""+s.key),s.ref!==void 0&&(f=s.ref);for(t in s)E.call(s,t)&&!D.hasOwnProperty(t)&&(l[t]=s[t]);if(o&&o.defaultProps)for(t in s=o.defaultProps,s)l[t]===void 0&&(l[t]=s[t]);return{$$typeof:T,type:o,key:d,ref:f,props:l,_owner:O.current}}p.Fragment=C,p.jsx=j,p.jsxs=j,v.exports=p;var e=v.exports;const y=({message:o,botName:s,userName:a})=>{const t=o.sender==="bot",l=d=>d.toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"});return e.jsx("div",{className:`cw-flex cw-mb-4 message-animation ${t?"cw-justify-start":"cw-justify-end"}`,children:e.jsxs("div",{className:`cw-max-w-xs cw-lg:max-w-md cw-px-4 cw-py-2 cw-rounded-lg cw-break-words ${t?"cw-bg-gray-200 cw-text-gray-800":"cw-bg-primary-500 cw-text-white"}`,children:[e.jsxs("div",{className:"cw-flex cw-items-center cw-mb-1",children:[e.jsx("span",{className:"cw-text-xs cw-font-semibold",children:t?s:a}),e.jsx("span",{className:"cw-text-xs cw-opacity-70 cw-ml-2",children:l(o.timestamp)})]}),e.jsx("div",{className:"cw-text-sm",children:o.text})]})})},g=({title:o="Chat Support",placeholder:s="Type your message...",onSendMessage:a,messages:t=[],className:l="",botName:d="Support Bot",userName:f="You",height:W="400px",width:M="350px",position:x="inline",theme:w="light"})=>{const[L,_]=c.useState([]),[u,N]=c.useState(""),[h,P]=c.useState(!1),k=c.useRef(null),I=c.useRef(null),b=t.length>0?t:L,H=r=>{const m=["Thanks for your message! How can I help you today?","I understand your concern. Let me assist you with that.","That's a great question! Here's what I can tell you...","I'm here to help! Can you provide more details?","Thank you for reaching out. I'll do my best to assist you."],i=r.toLowerCase();return i.includes("hello")||i.includes("hi")?"Hello! Welcome to our support chat. How can I help you today?":i.includes("help")?"I'm here to help! What do you need assistance with?":i.includes("price")||i.includes("cost")?"I can help you with pricing information. What specific product or service are you interested in?":m[Math.floor(Math.random()*m.length)]},B=()=>{var r;(r=k.current)==null||r.scrollIntoView({behavior:"smooth"})};c.useEffect(()=>{B()},[b]);const R=()=>{var m;if(!u.trim())return;const r={id:Date.now().toString(),text:u.trim(),sender:"user",timestamp:new Date};t.length>0?a==null||a(u.trim()):(_(i=>[...i,r]),setTimeout(()=>{const i={id:(Date.now()+1).toString(),text:H(u.trim()),sender:"bot",timestamp:new Date};_(K=>[...K,i])},1e3)),N(""),(m=I.current)==null||m.focus()},z=r=>{r.key==="Enter"&&!r.shiftKey&&(r.preventDefault(),R())},F={height:h?"auto":W,width:M,...x!=="inline"&&{position:"fixed",bottom:"20px",[x==="bottom-right"?"right":"left"]:"20px",zIndex:1e3}};return e.jsxs("div",{className:`chat-widget-container cw-bg-white cw-border cw-border-gray-300 cw-rounded-lg cw-shadow-lg cw-flex cw-flex-col ${w==="dark"?"cw-bg-gray-800 cw-border-gray-600":""} ${l}`,style:F,children:[e.jsxs("div",{className:`cw-flex cw-items-center cw-justify-between cw-p-4 cw-border-b cw-bg-primary-500 cw-text-white cw-rounded-t-lg ${w==="dark"?"cw-border-gray-600":"cw-border-gray-200"}`,children:[e.jsx("h3",{className:"cw-font-semibold cw-text-sm",children:o}),x!=="inline"&&e.jsx("button",{onClick:()=>P(!h),className:"cw-text-white cw-hover:bg-primary-600 cw-rounded cw-p-1 cw-transition-colors",children:h?"▲":"▼"})]}),!h&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:`cw-flex-1 cw-overflow-y-auto cw-p-4 chat-messages ${w==="dark"?"cw-bg-gray-700":"cw-bg-gray-50"}`,style:{maxHeight:"calc(100% - 120px)"},children:[b.length===0&&e.jsx("div",{className:`cw-text-center cw-text-gray-500 cw-text-sm cw-mt-8 ${w==="dark"?"cw-text-gray-400":""}`,children:"Start a conversation by typing a message below."}),b.map(r=>e.jsx(y,{message:r,botName:d,userName:f},r.id)),e.jsx("div",{ref:k})]}),e.jsx("div",{className:`cw-p-4 cw-border-t ${w==="dark"?"cw-border-gray-600 cw-bg-gray-800":"cw-border-gray-200"}`,children:e.jsxs("div",{className:"cw-flex cw-space-x-2 ",children:[e.jsx("input",{ref:I,type:"text",value:u,onChange:r=>N(r.target.value),onKeyDown:z,placeholder:s,className:` cw-w-full cw-flex-1 cw-px-3 cw-py-2 cw-border cw-rounded-md cw-text-sm cw-focus:outline-none cw-focus:ring-2 cw-focus:ring-primary-500 ${w==="dark"?"cw-bg-gray-700 cw-border-gray-600 cw-text-white cw-placeholder-gray-400":"cw-bg-white cw-border-gray-300"}`}),e.jsx("button",{onClick:R,disabled:!u.trim(),className:"cw-bg-primary-500 cw-text-white cw-px-4 cw-py-2 cw-rounded-md cw-text-sm cw-font-medium cw-hover:bg-primary-600 cw-disabled:opacity-50 cw-disabled:cursor-not-allowed cw-transition-colors",children:"Send"})]})})]})]})};typeof window<"u"&&(window.ChatWidget={ChatWidget:g,Message:y}),n.ChatWidget=g,n.Message=y,n.default=g,Object.defineProperties(n,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});
|
package/dist/dev.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { default as ChatWidget } from './ChatWidget';
|
|
2
|
+
import { default as Message } from './Message';
|
|
3
|
+
|
|
4
|
+
export { ChatWidget, Message };
|
|
5
|
+
export * from './types';
|
|
6
|
+
export { ChatWidget as default };
|
|
7
|
+
declare global {
|
|
8
|
+
interface Window {
|
|
9
|
+
ChatWidget: {
|
|
10
|
+
ChatWidget: typeof ChatWidget;
|
|
11
|
+
Message: typeof Message;
|
|
12
|
+
};
|
|
13
|
+
React: any;
|
|
14
|
+
ReactDOM: any;
|
|
15
|
+
}
|
|
16
|
+
}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export interface Message {
|
|
2
|
+
id: string;
|
|
3
|
+
text: string;
|
|
4
|
+
sender: 'user' | 'bot';
|
|
5
|
+
timestamp: Date;
|
|
6
|
+
}
|
|
7
|
+
export interface ChatWidgetProps {
|
|
8
|
+
title?: string;
|
|
9
|
+
placeholder?: string;
|
|
10
|
+
onSendMessage?: (message: string) => void;
|
|
11
|
+
messages?: Message[];
|
|
12
|
+
className?: string;
|
|
13
|
+
botName?: string;
|
|
14
|
+
userName?: string;
|
|
15
|
+
height?: string;
|
|
16
|
+
width?: string;
|
|
17
|
+
position?: 'bottom-right' | 'bottom-left' | 'inline';
|
|
18
|
+
theme?: 'light' | 'dark';
|
|
19
|
+
}
|
|
20
|
+
export interface ChatWidgetConfig {
|
|
21
|
+
apiEndpoint?: string;
|
|
22
|
+
apiKey?: string;
|
|
23
|
+
autoReply?: boolean;
|
|
24
|
+
welcomeMessage?: string;
|
|
25
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "interview-widget",
|
|
3
|
+
"type": "module",
|
|
4
|
+
"version": "1.0.0",
|
|
5
|
+
"description": "Advanced React interview widget with STT, TTS, camera access, and ML-powered analysis",
|
|
6
|
+
"main": "dist/chat-widget.umd.js",
|
|
7
|
+
"module": "dist/chat-widget.es.js",
|
|
8
|
+
"types": "dist/index.d.ts",
|
|
9
|
+
"unpkg": "dist/chat-widget.umd.js",
|
|
10
|
+
"jsdelivr": "dist/chat-widget.umd.js",
|
|
11
|
+
"files": [
|
|
12
|
+
"dist"
|
|
13
|
+
],
|
|
14
|
+
"scripts": {
|
|
15
|
+
"dev": "vite",
|
|
16
|
+
"build": "tsc && vite build",
|
|
17
|
+
"build:cdn": "npm run build && npm run copy:examples",
|
|
18
|
+
"copy:examples": "mkdir -p dist/examples && cp examples/*.html dist/examples/",
|
|
19
|
+
"preview": "vite preview",
|
|
20
|
+
"type-check": "tsc --noEmit"
|
|
21
|
+
},
|
|
22
|
+
"peerDependencies": {
|
|
23
|
+
"react": ">=18.0.0",
|
|
24
|
+
"react-dom": ">=18.0.0"
|
|
25
|
+
},
|
|
26
|
+
"devDependencies": {
|
|
27
|
+
"@types/node": "^20.0.0",
|
|
28
|
+
"@types/react": "^18.2.0",
|
|
29
|
+
"@types/react-dom": "^18.2.0",
|
|
30
|
+
"@typescript-eslint/eslint-plugin": "^6.0.0",
|
|
31
|
+
"@typescript-eslint/parser": "^6.0.0",
|
|
32
|
+
"@vitejs/plugin-react": "^4.0.0",
|
|
33
|
+
"autoprefixer": "^10.4.14",
|
|
34
|
+
"postcss": "^8.4.24",
|
|
35
|
+
"react": "^18.2.0",
|
|
36
|
+
"react-dom": "^18.2.0",
|
|
37
|
+
"tailwindcss": "^3.3.0",
|
|
38
|
+
"typescript": "^5.0.2",
|
|
39
|
+
"vite": "^4.4.0",
|
|
40
|
+
"vite-plugin-dts": "^3.0.0"
|
|
41
|
+
},
|
|
42
|
+
"keywords": [
|
|
43
|
+
"react",
|
|
44
|
+
"chat",
|
|
45
|
+
"widget",
|
|
46
|
+
"cdn",
|
|
47
|
+
"embed"
|
|
48
|
+
],
|
|
49
|
+
"author": "Your Name",
|
|
50
|
+
"license": "MIT"
|
|
51
|
+
}
|