interview-widget 0.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.
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,4 @@
1
+ import { default as React } from 'react';
2
+ import { ChatWidgetProps } from './types';
3
+ declare const ChatWidget: React.FC<ChatWidgetProps>;
4
+ export default ChatWidget;
@@ -0,0 +1,9 @@
1
+ import { default as React } from 'react';
2
+ import { Message as MessageType } from './types';
3
+ interface MessageProps {
4
+ message: MessageType;
5
+ botName: string;
6
+ userName: string;
7
+ }
8
+ declare const Message: React.FC<MessageProps>;
9
+ 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-2{margin-bottom:.5rem!important}.cw-mb-4{margin-bottom:1rem!important}.cw-mb-6{margin-bottom:1.5rem!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-grid-cols-3{grid-template-columns:repeat(3,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-4{gap:1rem!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-100{--tw-bg-opacity: 1 !important;background-color:rgb(243 244 246 / 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-blue-600{--tw-text-opacity: 1 !important;color:rgb(37 99 235 / var(--tw-text-opacity, 1))!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-green-600{--tw-text-opacity: 1 !important;color:rgb(22 163 74 / var(--tw-text-opacity, 1))!important}.cw-text-purple-600{--tw-text-opacity: 1 !important;color:rgb(147 51 234 / 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,193 @@
1
+ import { useState as p, useRef as j, useEffect as _ } from "react";
2
+ var k = { exports: {} }, u = {};
3
+ /**
4
+ * @license React
5
+ * react-jsx-runtime.production.js
6
+ *
7
+ * Copyright (c) Meta Platforms, Inc. and 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 A = Symbol.for("react.transitional.element"), L = Symbol.for("react.fragment");
13
+ function N(a, r, s) {
14
+ var c = null;
15
+ if (s !== void 0 && (c = "" + s), r.key !== void 0 && (c = "" + r.key), "key" in r) {
16
+ s = {};
17
+ for (var n in r)
18
+ n !== "key" && (s[n] = r[n]);
19
+ } else s = r;
20
+ return r = s.ref, {
21
+ $$typeof: A,
22
+ type: a,
23
+ key: c,
24
+ ref: r !== void 0 ? r : null,
25
+ props: s
26
+ };
27
+ }
28
+ u.Fragment = L;
29
+ u.jsx = N;
30
+ u.jsxs = N;
31
+ k.exports = u;
32
+ var e = k.exports;
33
+ const I = ({ message: a, botName: r, userName: s }) => {
34
+ const c = a.sender === "bot", n = (m) => m.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
35
+ return /* @__PURE__ */ e.jsx("div", { className: `cw-flex cw-mb-4 message-animation ${c ? "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 ${c ? "cw-bg-gray-200 cw-text-gray-800" : "cw-bg-primary-500 cw-text-white"}`, children: [
36
+ /* @__PURE__ */ e.jsxs("div", { className: "cw-flex cw-items-center cw-mb-1", children: [
37
+ /* @__PURE__ */ e.jsx("span", { className: "cw-text-xs cw-font-semibold", children: c ? r : s }),
38
+ /* @__PURE__ */ e.jsx("span", { className: "cw-text-xs cw-opacity-70 cw-ml-2", children: n(a.timestamp) })
39
+ ] }),
40
+ /* @__PURE__ */ e.jsx("div", { className: "cw-text-sm", children: a.text })
41
+ ] }) });
42
+ }, P = ({
43
+ title: a = "Chat Support",
44
+ placeholder: r = "Type your message...",
45
+ onSendMessage: s,
46
+ messages: c = [],
47
+ className: n = "",
48
+ botName: m = "Support Bot",
49
+ userName: T = "You",
50
+ height: E = "400px",
51
+ width: R = "350px",
52
+ position: x = "inline",
53
+ theme: i = "light"
54
+ }) => {
55
+ const [$, g] = p([]), [l, y] = p(""), [d, C] = p(!1), f = j(null), b = j(null), h = c.length > 0 ? c : $, S = (t) => {
56
+ const w = [
57
+ "Thanks for your message! How can I help you today?",
58
+ "I understand your concern. Let me assist you with that.",
59
+ "That's a great question! Here's what I can tell you...",
60
+ "I'm here to help! Can you provide more details?",
61
+ "Thank you for reaching out. I'll do my best to assist you."
62
+ ], o = t.toLowerCase();
63
+ 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?" : w[Math.floor(Math.random() * w.length)] || "I'm here to help!";
64
+ }, D = () => {
65
+ var t;
66
+ (t = f.current) == null || t.scrollIntoView({ behavior: "smooth" });
67
+ };
68
+ _(() => {
69
+ D();
70
+ }, [h]);
71
+ const v = () => {
72
+ var w;
73
+ if (!l.trim()) return;
74
+ const t = {
75
+ id: Date.now().toString(),
76
+ text: l.trim(),
77
+ sender: "user",
78
+ timestamp: /* @__PURE__ */ new Date()
79
+ };
80
+ c.length > 0 ? s == null || s(l.trim()) : (g((o) => [...o, t]), setTimeout(() => {
81
+ const o = {
82
+ id: (Date.now() + 1).toString(),
83
+ text: S(l.trim()),
84
+ sender: "bot",
85
+ timestamp: /* @__PURE__ */ new Date()
86
+ };
87
+ g((W) => [...W, o]);
88
+ }, 1e3)), y(""), (w = b.current) == null || w.focus();
89
+ }, M = (t) => {
90
+ t.key === "Enter" && !t.shiftKey && (t.preventDefault(), v());
91
+ }, H = {
92
+ height: d ? "auto" : E,
93
+ width: R,
94
+ ...x !== "inline" && {
95
+ position: "fixed",
96
+ bottom: "20px",
97
+ [x === "bottom-right" ? "right" : "left"]: "20px",
98
+ zIndex: 1e3
99
+ }
100
+ };
101
+ return /* @__PURE__ */ e.jsxs(
102
+ "div",
103
+ {
104
+ className: `chat-widget-container cw-bg-white cw-border cw-border-gray-300 cw-rounded-lg cw-shadow-lg cw-flex cw-flex-col ${i === "dark" ? "cw-bg-gray-800 cw-border-gray-600" : ""} ${n}`,
105
+ style: H,
106
+ children: [
107
+ /* @__PURE__ */ e.jsxs(
108
+ "div",
109
+ {
110
+ 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 ${i === "dark" ? "cw-border-gray-600" : "cw-border-gray-200"}`,
111
+ children: [
112
+ /* @__PURE__ */ e.jsx("h3", { className: "cw-font-semibold cw-text-sm", children: a }),
113
+ x !== "inline" && /* @__PURE__ */ e.jsx(
114
+ "button",
115
+ {
116
+ onClick: () => C(!d),
117
+ className: "cw-text-white cw-hover:bg-primary-600 cw-rounded cw-p-1 cw-transition-colors",
118
+ children: d ? "▲" : "▼"
119
+ }
120
+ )
121
+ ]
122
+ }
123
+ ),
124
+ !d && /* @__PURE__ */ e.jsxs(e.Fragment, { children: [
125
+ /* @__PURE__ */ e.jsxs(
126
+ "div",
127
+ {
128
+ className: `cw-flex-1 cw-overflow-y-auto cw-p-4 chat-messages ${i === "dark" ? "cw-bg-gray-700" : "cw-bg-gray-50"}`,
129
+ style: { maxHeight: "calc(100% - 120px)" },
130
+ children: [
131
+ h.length === 0 && /* @__PURE__ */ e.jsx(
132
+ "div",
133
+ {
134
+ className: `cw-text-center cw-text-gray-500 cw-text-sm cw-mt-8 ${i === "dark" ? "cw-text-gray-400" : ""}`,
135
+ children: "Start a conversation by typing a message below."
136
+ }
137
+ ),
138
+ h.map((t) => /* @__PURE__ */ e.jsx(
139
+ I,
140
+ {
141
+ message: t,
142
+ botName: m,
143
+ userName: T
144
+ },
145
+ t.id
146
+ )),
147
+ /* @__PURE__ */ e.jsx("div", { ref: f })
148
+ ]
149
+ }
150
+ ),
151
+ /* @__PURE__ */ e.jsx(
152
+ "div",
153
+ {
154
+ className: `cw-p-4 cw-border-t ${i === "dark" ? "cw-border-gray-600 cw-bg-gray-800" : "cw-border-gray-200"}`,
155
+ children: /* @__PURE__ */ e.jsxs("div", { className: "cw-flex cw-space-x-2 ", children: [
156
+ /* @__PURE__ */ e.jsx(
157
+ "input",
158
+ {
159
+ ref: b,
160
+ type: "text",
161
+ value: l,
162
+ onChange: (t) => y(t.target.value),
163
+ onKeyDown: M,
164
+ placeholder: r,
165
+ 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 ${i === "dark" ? "cw-bg-gray-700 cw-border-gray-600 cw-text-white cw-placeholder-gray-400" : "cw-bg-white cw-border-gray-300"}`
166
+ }
167
+ ),
168
+ /* @__PURE__ */ e.jsx(
169
+ "button",
170
+ {
171
+ onClick: v,
172
+ disabled: !l.trim(),
173
+ 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",
174
+ children: "Send"
175
+ }
176
+ )
177
+ ] })
178
+ }
179
+ )
180
+ ] })
181
+ ]
182
+ }
183
+ );
184
+ };
185
+ typeof window < "u" && (window.ChatWidget = {
186
+ ChatWidget: P,
187
+ Message: I
188
+ });
189
+ export {
190
+ P as ChatWidget,
191
+ I as Message,
192
+ P as default
193
+ };
@@ -0,0 +1,9 @@
1
+ (function(i,o){typeof exports=="object"&&typeof module<"u"?o(exports,require("react")):typeof define=="function"&&define.amd?define(["exports","react"],o):(i=typeof globalThis<"u"?globalThis:i||self,o(i.ChatWidget={},i.React))})(this,function(i,o){"use strict";var b={exports:{}},m={};/**
2
+ * @license React
3
+ * react-jsx-runtime.production.js
4
+ *
5
+ * Copyright (c) Meta Platforms, Inc. and 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 R=Symbol.for("react.transitional.element"),C=Symbol.for("react.fragment");function v(a,r,s){var c=null;if(s!==void 0&&(c=""+s),r.key!==void 0&&(c=""+r.key),"key"in r){s={};for(var l in r)l!=="key"&&(s[l]=r[l])}else s=r;return r=s.ref,{$$typeof:R,type:a,key:c,ref:r!==void 0?r:null,props:s}}m.Fragment=C,m.jsx=v,m.jsxs=v,b.exports=m;var e=b.exports;const x=({message:a,botName:r,userName:s})=>{const c=a.sender==="bot",l=g=>g.toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"});return e.jsx("div",{className:`cw-flex cw-mb-4 message-animation ${c?"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 ${c?"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:c?r:s}),e.jsx("span",{className:"cw-text-xs cw-opacity-70 cw-ml-2",children:l(a.timestamp)})]}),e.jsx("div",{className:"cw-text-sm",children:a.text})]})})},p=({title:a="Chat Support",placeholder:r="Type your message...",onSendMessage:s,messages:c=[],className:l="",botName:g="Support Bot",userName:E="You",height:S="400px",width:$="350px",position:y="inline",theme:d="light"})=>{const[M,j]=o.useState([]),[w,k]=o.useState(""),[h,W]=o.useState(!1),T=o.useRef(null),N=o.useRef(null),f=c.length>0?c:M,_=t=>{const u=["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."],n=t.toLowerCase();return n.includes("hello")||n.includes("hi")?"Hello! Welcome to our support chat. How can I help you today?":n.includes("help")?"I'm here to help! What do you need assistance with?":n.includes("price")||n.includes("cost")?"I can help you with pricing information. What specific product or service are you interested in?":u[Math.floor(Math.random()*u.length)]||"I'm here to help!"},D=()=>{var t;(t=T.current)==null||t.scrollIntoView({behavior:"smooth"})};o.useEffect(()=>{D()},[f]);const I=()=>{var u;if(!w.trim())return;const t={id:Date.now().toString(),text:w.trim(),sender:"user",timestamp:new Date};c.length>0?s==null||s(w.trim()):(j(n=>[...n,t]),setTimeout(()=>{const n={id:(Date.now()+1).toString(),text:_(w.trim()),sender:"bot",timestamp:new Date};j(A=>[...A,n])},1e3)),k(""),(u=N.current)==null||u.focus()},H=t=>{t.key==="Enter"&&!t.shiftKey&&(t.preventDefault(),I())},P={height:h?"auto":S,width:$,...y!=="inline"&&{position:"fixed",bottom:"20px",[y==="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 ${d==="dark"?"cw-bg-gray-800 cw-border-gray-600":""} ${l}`,style:P,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 ${d==="dark"?"cw-border-gray-600":"cw-border-gray-200"}`,children:[e.jsx("h3",{className:"cw-font-semibold cw-text-sm",children:a}),y!=="inline"&&e.jsx("button",{onClick:()=>W(!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 ${d==="dark"?"cw-bg-gray-700":"cw-bg-gray-50"}`,style:{maxHeight:"calc(100% - 120px)"},children:[f.length===0&&e.jsx("div",{className:`cw-text-center cw-text-gray-500 cw-text-sm cw-mt-8 ${d==="dark"?"cw-text-gray-400":""}`,children:"Start a conversation by typing a message below."}),f.map(t=>e.jsx(x,{message:t,botName:g,userName:E},t.id)),e.jsx("div",{ref:T})]}),e.jsx("div",{className:`cw-p-4 cw-border-t ${d==="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:N,type:"text",value:w,onChange:t=>k(t.target.value),onKeyDown:H,placeholder:r,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 ${d==="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:I,disabled:!w.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:p,Message:x}),i.ChatWidget=p,i.Message=x,i.default=p,Object.defineProperties(i,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});
package/dist/dev.d.ts ADDED
File without changes
@@ -0,0 +1,15 @@
1
+ import { default as ChatWidget } from './ChatWidget';
2
+ import { default as Message } from './Message';
3
+ export { ChatWidget, Message };
4
+ export * from './types';
5
+ export { ChatWidget as default };
6
+ declare global {
7
+ interface Window {
8
+ ChatWidget: {
9
+ ChatWidget: typeof ChatWidget;
10
+ Message: typeof Message;
11
+ };
12
+ React: any;
13
+ ReactDOM: any;
14
+ }
15
+ }
@@ -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": "0.0.1",
5
+ "description": "Advanced React interview widget with STT, TTS, camera access, and ML-powered analysis",
6
+ "main": "dist/widget.umd.js",
7
+ "module": "dist/widget.es.js",
8
+ "types": "dist/index.d.ts",
9
+ "unpkg": "dist/widget.umd.js",
10
+ "jsdelivr": "dist/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": "^22.0.0",
28
+ "@types/react": "npm:types-react@^19.0.0-rc.1",
29
+ "@types/react-dom": "npm:types-react-dom@^19.0.0-rc.1",
30
+ "@typescript-eslint/eslint-plugin": "^8.0.0",
31
+ "@typescript-eslint/parser": "^8.0.0",
32
+ "@vitejs/plugin-react": "^4.3.0",
33
+ "autoprefixer": "^10.4.20",
34
+ "postcss": "^8.4.47",
35
+ "react": "^19.0.0-rc.1",
36
+ "react-dom": "^19.0.0-rc.1",
37
+ "tailwindcss": "^3.4.0",
38
+ "typescript": "^5.6.0",
39
+ "vite": "^5.4.0",
40
+ "vite-plugin-dts": "^4.0.0"
41
+ },
42
+ "keywords": [
43
+ "react",
44
+ "chat",
45
+ "widget",
46
+ "cdn",
47
+ "embed"
48
+ ],
49
+ "author": "Your Name",
50
+ "license": "MIT"
51
+ }