@inappai/react 0.1.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 +44 -0
- package/dist/index.css +2 -0
- package/dist/index.css.map +1 -0
- package/dist/index.d.mts +56 -0
- package/dist/index.d.ts +56 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +8 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +63 -0
package/README.md
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# @inappai/react
|
|
2
|
+
|
|
3
|
+
Beautiful, customizable AI chat component for React applications.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @inappai/react
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```tsx
|
|
14
|
+
import { InAppAI } from '@inappai/react';
|
|
15
|
+
import '@inappai/react/styles.css';
|
|
16
|
+
|
|
17
|
+
function App() {
|
|
18
|
+
return (
|
|
19
|
+
<InAppAI
|
|
20
|
+
endpoint="https://api.inappai.com/api/{subscriptionId}"
|
|
21
|
+
position="bottom-right"
|
|
22
|
+
theme="light"
|
|
23
|
+
/>
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Documentation
|
|
29
|
+
|
|
30
|
+
See the [main README](../../README.md) for full documentation, examples, and API reference.
|
|
31
|
+
|
|
32
|
+
## Features
|
|
33
|
+
|
|
34
|
+
- ✨ Beautiful UI out of the box
|
|
35
|
+
- 🎨 Fully customizable with themes and custom styles
|
|
36
|
+
- 📱 Responsive design
|
|
37
|
+
- 🌓 Light & dark mode
|
|
38
|
+
- ⚡ Zero config
|
|
39
|
+
- 🔧 Full TypeScript support
|
|
40
|
+
- 📦 Minimal bundle size
|
|
41
|
+
|
|
42
|
+
## License
|
|
43
|
+
|
|
44
|
+
MIT © [InAppAI](https://github.com/InAppAI)
|
package/dist/index.css
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
:root{--inapp-ai-primary: #667eea;--inapp-ai-primary-dark: #764ba2;--inapp-ai-primary-gradient: linear-gradient(135deg, #667eea 0%, #764ba2 100%);--inapp-ai-bg-primary: #ffffff;--inapp-ai-bg-secondary: #f8f9fa;--inapp-ai-bg-tertiary: #e9ecef;--inapp-ai-text-primary: #333333;--inapp-ai-text-secondary: #666666;--inapp-ai-text-tertiary: #999999;--inapp-ai-text-inverse: #ffffff;--inapp-ai-border-light: #e0e0e0;--inapp-ai-border-medium: #cccccc;--inapp-ai-border-dark: #999999;--inapp-ai-user-bg: #667eea;--inapp-ai-user-text: #ffffff;--inapp-ai-assistant-bg: #f0f2f5;--inapp-ai-assistant-text: #333333;--inapp-ai-input-bg: #ffffff;--inapp-ai-input-border: #e0e0e0;--inapp-ai-input-text: #333333;--inapp-ai-input-placeholder: #999999;--inapp-ai-button-bg: var(--inapp-ai-primary-gradient);--inapp-ai-button-text: #ffffff;--inapp-ai-button-hover-scale: 1.1;--inapp-ai-shadow-sm: 0 2px 8px rgba(0, 0, 0, .1);--inapp-ai-shadow-md: 0 4px 12px rgba(0, 0, 0, .15);--inapp-ai-shadow-lg: 0 8px 24px rgba(0, 0, 0, .2);--inapp-ai-border-radius: 12px;--inapp-ai-border-radius-sm: 8px;--inapp-ai-border-radius-lg: 16px;--inapp-ai-transition: all .3s ease;--inapp-ai-transition-fast: all .15s ease}.inapp-ai-theme-dark{--inapp-ai-bg-primary: #1a1a1a;--inapp-ai-bg-secondary: #2d2d2d;--inapp-ai-bg-tertiary: #404040;--inapp-ai-text-primary: #ffffff;--inapp-ai-text-secondary: #cccccc;--inapp-ai-text-tertiary: #999999;--inapp-ai-border-light: #404040;--inapp-ai-border-medium: #555555;--inapp-ai-border-dark: #666666;--inapp-ai-user-bg: #667eea;--inapp-ai-user-text: #ffffff;--inapp-ai-assistant-bg: #2d2d2d;--inapp-ai-assistant-text: #ffffff;--inapp-ai-input-bg: #2d2d2d;--inapp-ai-input-border: #404040;--inapp-ai-input-text: #ffffff;--inapp-ai-input-placeholder: #999999;--inapp-ai-shadow-sm: 0 2px 8px rgba(0, 0, 0, .3);--inapp-ai-shadow-md: 0 4px 12px rgba(0, 0, 0, .4);--inapp-ai-shadow-lg: 0 8px 24px rgba(0, 0, 0, .5)}.inapp-ai-theme-professional{--inapp-ai-primary: #0052cc;--inapp-ai-primary-dark: #003d99;--inapp-ai-primary-gradient: linear-gradient(135deg, #0052cc 0%, #003d99 100%);--inapp-ai-bg-primary: #ffffff;--inapp-ai-bg-secondary: #f7f8f9;--inapp-ai-bg-tertiary: #ebecf0;--inapp-ai-text-primary: #172b4d;--inapp-ai-text-secondary: #5e6c84;--inapp-ai-text-tertiary: #8993a4;--inapp-ai-user-bg: #0052cc;--inapp-ai-user-text: #ffffff;--inapp-ai-assistant-bg: #f7f8f9;--inapp-ai-assistant-text: #172b4d;--inapp-ai-border-light: #dfe1e6;--inapp-ai-border-medium: #c1c7d0;--inapp-ai-border-radius: 8px}.inapp-ai-theme-playful{--inapp-ai-primary: #ff6b6b;--inapp-ai-primary-dark: #ee5a6f;--inapp-ai-primary-gradient: linear-gradient(135deg, #ff6b6b 0%, #f06595 50%, #cc5de8 100%);--inapp-ai-bg-primary: #fff5f7;--inapp-ai-bg-secondary: #ffe3e3;--inapp-ai-bg-tertiary: #ffd4e5;--inapp-ai-text-primary: #2d0b3d;--inapp-ai-text-secondary: #5a1e72;--inapp-ai-text-tertiary: #8b4896;--inapp-ai-user-bg: linear-gradient(135deg, #ff6b6b 0%, #f06595 100%);--inapp-ai-user-text: #ffffff;--inapp-ai-assistant-bg: #ffe3e3;--inapp-ai-assistant-text: #2d0b3d;--inapp-ai-border-radius: 20px;--inapp-ai-border-radius-lg: 24px;--inapp-ai-border-light: #ffc6d9}.inapp-ai-theme-minimal{--inapp-ai-primary: #000000;--inapp-ai-primary-dark: #1a1a1a;--inapp-ai-primary-gradient: linear-gradient(135deg, #000000 0%, #333333 100%);--inapp-ai-bg-primary: #ffffff;--inapp-ai-bg-secondary: #fafafa;--inapp-ai-bg-tertiary: #f5f5f5;--inapp-ai-text-primary: #000000;--inapp-ai-text-secondary: #333333;--inapp-ai-text-tertiary: #666666;--inapp-ai-user-bg: #000000;--inapp-ai-user-text: #ffffff;--inapp-ai-assistant-bg: #fafafa;--inapp-ai-assistant-text: #000000;--inapp-ai-border-light: #e0e0e0;--inapp-ai-border-medium: #cccccc;--inapp-ai-border-radius: 4px;--inapp-ai-border-radius-sm: 2px;--inapp-ai-border-radius-lg: 6px;--inapp-ai-shadow-sm: 0 1px 3px rgba(0, 0, 0, .08);--inapp-ai-shadow-md: 0 2px 6px rgba(0, 0, 0, .1);--inapp-ai-shadow-lg: 0 4px 12px rgba(0, 0, 0, .12)}.inapp-ai-theme-ocean{--inapp-ai-primary: #0077be;--inapp-ai-primary-dark: #005a8d;--inapp-ai-primary-gradient: linear-gradient(135deg, #0077be 0%, #0096d6 100%);--inapp-ai-bg-primary: #f0f8ff;--inapp-ai-bg-secondary: #e6f3ff;--inapp-ai-bg-tertiary: #cce7ff;--inapp-ai-text-primary: #003d5c;--inapp-ai-text-secondary: #005a8d;--inapp-ai-text-tertiary: #0077be;--inapp-ai-user-bg: #0077be;--inapp-ai-user-text: #ffffff;--inapp-ai-assistant-bg: #e6f3ff;--inapp-ai-assistant-text: #003d5c}.inapp-ai-theme-sunset{--inapp-ai-primary: #ff6b35;--inapp-ai-primary-dark: #f7931e;--inapp-ai-primary-gradient: linear-gradient(135deg, #ff6b35 0%, #f7931e 50%, #ffc947 100%);--inapp-ai-bg-primary: #fff8f3;--inapp-ai-bg-secondary: #ffe8d6;--inapp-ai-bg-tertiary: #ffd4b8;--inapp-ai-text-primary: #5c2400;--inapp-ai-text-secondary: #8b3a00;--inapp-ai-text-tertiary: #b85000;--inapp-ai-user-bg: linear-gradient(135deg, #ff6b35 0%, #f7931e 100%);--inapp-ai-user-text: #ffffff;--inapp-ai-assistant-bg: #ffe8d6;--inapp-ai-assistant-text: #5c2400}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.inapp-ai-button{position:fixed;width:60px;height:60px;border-radius:50%;border:none;background:var(--inapp-ai-button-bg);color:var(--inapp-ai-button-text);font-size:24px;cursor:pointer;box-shadow:var(--inapp-ai-shadow-md);transition:var(--inapp-ai-transition);z-index:10001;display:flex;align-items:center;justify-content:center}.inapp-ai-button:hover{transform:scale(var(--inapp-ai-button-hover-scale));box-shadow:var(--inapp-ai-shadow-lg)}.inapp-ai-button:active{transform:scale(.95)}.inapp-ai-offline-indicator{position:absolute;top:8px;right:8px;width:12px;height:12px;background:#dc3545;border-radius:50%;border:2px solid white}.inapp-ai-bottom-right{bottom:20px;right:20px}.inapp-ai-bottom-left{bottom:20px;left:20px}.inapp-ai-top-right{top:20px;right:20px}.inapp-ai-top-left{top:20px;left:20px}.inapp-ai-window{position:fixed;background:var(--inapp-ai-bg-primary);box-shadow:var(--inapp-ai-shadow-lg);display:flex;flex-direction:column;z-index:10000;transition:var(--inapp-ai-transition)}.inapp-ai-popup{width:380px;max-width:calc(100vw - 40px);height:600px;max-height:calc(100vh - 100px);border-radius:var(--inapp-ai-border-radius-lg);animation:slideUp .3s ease-out}.inapp-ai-popup.inapp-ai-bottom-right{bottom:100px;right:20px}.inapp-ai-popup.inapp-ai-bottom-left{bottom:100px;left:20px}.inapp-ai-popup.inapp-ai-top-right{top:100px;right:20px}.inapp-ai-popup.inapp-ai-top-left{top:100px;left:20px}@keyframes slideUp{0%{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}.inapp-ai-sidebar{top:30px;height:calc(100vh - 60px);width:400px;max-width:100vw;border-radius:0;animation:slideIn .3s ease-out}.inapp-ai-sidebar-left{left:0;border-right:1px solid var(--inapp-ai-border-light);box-shadow:8px 0 32px #0000001f}.inapp-ai-sidebar-right{right:0;border-left:1px solid var(--inapp-ai-border-light);box-shadow:-8px 0 32px #0000001f}.inapp-ai-sidebar.inapp-ai-folded{width:60px}@keyframes slideIn{0%{opacity:0;transform:translate(-20px)}to{opacity:1;transform:translate(0)}}.inapp-ai-sidebar-right:not(.inapp-ai-folded){animation-name:slideInRight}@keyframes slideInRight{0%{opacity:0;transform:translate(20px)}to{opacity:1;transform:translate(0)}}.inapp-ai-fold-toggle{position:absolute;top:50%;transform:translateY(-50%);width:32px;height:64px;background:var(--inapp-ai-primary-gradient);color:var(--inapp-ai-text-inverse);border:none;cursor:pointer;font-size:16px;display:flex;align-items:center;justify-content:center;z-index:10;transition:var(--inapp-ai-transition-fast);box-shadow:var(--inapp-ai-shadow-sm)}.inapp-ai-sidebar-left .inapp-ai-fold-toggle{right:-16px;border-radius:0 var(--inapp-ai-border-radius-sm) var(--inapp-ai-border-radius-sm) 0}.inapp-ai-sidebar-right .inapp-ai-fold-toggle{left:-16px;border-radius:var(--inapp-ai-border-radius-sm) 0 0 var(--inapp-ai-border-radius-sm)}.inapp-ai-fold-toggle:hover{background:var(--inapp-ai-primary-dark);transform:translateY(-50%) scale(1.05)}.inapp-ai-fold-toggle:active{transform:translateY(-50%) scale(.95)}.inapp-ai-folded-content{display:flex;flex-direction:column;align-items:center;padding:20px 0;height:100%;gap:16px}.inapp-ai-folded-icon{font-size:32px;margin-top:20px;animation:pulse 2s infinite}.inapp-ai-folded-text{display:none}.inapp-ai-message-count{background:var(--inapp-ai-primary-gradient);color:var(--inapp-ai-text-inverse);width:24px;height:24px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:600;margin-top:8px;animation:bounce .5s ease-out}@keyframes bounce{0%,to{transform:scale(1)}50%{transform:scale(1.2)}}.inapp-ai-panel{position:relative;top:0;height:100vh;min-height:100vh;max-height:100vh;border-radius:0;box-shadow:none;display:flex;flex-direction:column}.inapp-ai-panel-left{left:0;border-right:1px solid var(--inapp-ai-border-light)}.inapp-ai-panel-right{right:0;border-left:1px solid var(--inapp-ai-border-light)}.inapp-ai-resize-handle{position:absolute;top:0;width:6px;height:100%;background:transparent;cursor:col-resize;z-index:11;transition:background .2s}.inapp-ai-resize-handle:hover{background:#667eea4d}.inapp-ai-resize-handle:active{background:#667eea80}.inapp-ai-resize-handle-right{right:0;border-right:2px solid transparent}.inapp-ai-resize-handle-left{left:0;border-left:2px solid transparent}.inapp-ai-resize-handle-right:hover,.inapp-ai-resize-handle-right:active{border-right-color:var(--inapp-ai-primary)}.inapp-ai-resize-handle-left:hover,.inapp-ai-resize-handle-left:active{border-left-color:var(--inapp-ai-primary)}.inapp-ai-panel .inapp-ai-header{border-radius:0}.inapp-ai-panel.inapp-ai-folded{width:60px;min-width:60px;max-width:60px}.inapp-ai-window.inapp-ai-theme-dark{background:#1e1e1e;color:#fff}.inapp-ai-sidebar-left.inapp-ai-theme-dark{border-right-color:#2d2d2d}.inapp-ai-sidebar-right.inapp-ai-theme-dark{border-left-color:#2d2d2d}.inapp-ai-header{padding:20px;background:var(--inapp-ai-primary-gradient);color:var(--inapp-ai-text-inverse);border-radius:var(--inapp-ai-border-radius-lg) var(--inapp-ai-border-radius-lg) 0 0;display:flex;justify-content:space-between;align-items:center;flex-shrink:0}.inapp-ai-sidebar .inapp-ai-header{border-radius:0}.inapp-ai-header-title{display:flex;align-items:center;gap:12px}.inapp-ai-header-icon{font-size:32px}.inapp-ai-header h3{margin:0;font-size:18px;font-weight:600}.inapp-ai-header p{margin:4px 0 0;font-size:12px;opacity:.9}.inapp-ai-status-connected,.inapp-ai-status-disconnected{display:flex;align-items:center;gap:6px}.inapp-ai-status-dot{width:8px;height:8px;border-radius:50%;background:#28a745;animation:pulse 2s infinite}.inapp-ai-status-disconnected .inapp-ai-status-dot{background:#dc3545}@keyframes pulse{0%,to{opacity:1}50%{opacity:.5}}.inapp-ai-close-btn{background:#fff3;border:none;color:#fff;width:32px;height:32px;border-radius:8px;cursor:pointer;font-size:18px;display:flex;align-items:center;justify-content:center;transition:background .2s}.inapp-ai-close-btn:hover{background:#ffffff4d}.inapp-ai-header-fold-btn{background:#fff3;border:none;color:#fff;width:32px;height:32px;border-radius:8px;cursor:pointer;font-size:16px;display:flex;align-items:center;justify-content:center;transition:background .2s}.inapp-ai-header-fold-btn:hover{background:#ffffff4d}.inapp-ai-error-banner{padding:12px 20px;background:#fff3cd;color:#856404;display:flex;align-items:center;gap:10px;font-size:14px;border-bottom:1px solid #ffeeba;flex-shrink:0}.inapp-ai-error-banner button{margin-left:auto;background:none;border:none;color:#856404;cursor:pointer;padding:4px 8px}.inapp-ai-messages{flex:1;overflow-y:auto;padding:20px;display:flex;flex-direction:column;gap:16px;min-height:0}.inapp-ai-messages::-webkit-scrollbar{width:8px}.inapp-ai-messages::-webkit-scrollbar-track{background:#f1f1f1}.inapp-ai-messages::-webkit-scrollbar-thumb{background:#c1c1c1;border-radius:4px}.inapp-ai-messages::-webkit-scrollbar-thumb:hover{background:#a1a1a1}.inapp-ai-empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;text-align:center;color:#6c757d;padding:40px}.inapp-ai-empty-icon{font-size:48px;margin-bottom:16px}.inapp-ai-empty-state h4{margin:0 0 8px;font-size:18px;color:#495057}.inapp-ai-empty-state p{margin:0;font-size:14px}.inapp-ai-message{display:flex;gap:12px;animation:messageSlideIn .3s ease-out}@keyframes messageSlideIn{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}.inapp-ai-message-user{flex-direction:row-reverse}.inapp-ai-message-icon{width:36px;height:36px;border-radius:50%;background:var(--inapp-ai-bg-secondary);display:flex;align-items:center;justify-content:center;font-size:20px;flex-shrink:0}.inapp-ai-message-user .inapp-ai-message-icon,.inapp-ai-message-assistant .inapp-ai-message-icon{background:var(--inapp-ai-primary-gradient)}.inapp-ai-message-content{flex:1;min-width:0}.inapp-ai-message-text{background:var(--inapp-ai-assistant-bg);color:var(--inapp-ai-assistant-text);padding:12px 16px;border-radius:var(--inapp-ai-border-radius);line-height:1.5;font-size:14px;word-wrap:break-word}.inapp-ai-message-user .inapp-ai-message-text{background:var(--inapp-ai-user-bg);color:var(--inapp-ai-user-text);border-radius:var(--inapp-ai-border-radius) var(--inapp-ai-border-radius) var(--inapp-ai-border-radius-sm) var(--inapp-ai-border-radius)}.inapp-ai-message-assistant .inapp-ai-message-text{border-radius:var(--inapp-ai-border-radius) var(--inapp-ai-border-radius) var(--inapp-ai-border-radius) var(--inapp-ai-border-radius-sm)}.inapp-ai-message-text p{margin:0 0 8px}.inapp-ai-message-text p:last-child{margin-bottom:0}.inapp-ai-message-text h1,.inapp-ai-message-text h2,.inapp-ai-message-text h3,.inapp-ai-message-text h4{margin:12px 0 8px;font-weight:600}.inapp-ai-message-text h1:first-child,.inapp-ai-message-text h2:first-child,.inapp-ai-message-text h3:first-child,.inapp-ai-message-text h4:first-child{margin-top:0}.inapp-ai-message-text h1{font-size:18px}.inapp-ai-message-text h2{font-size:16px}.inapp-ai-message-text h3{font-size:15px}.inapp-ai-message-text h4{font-size:14px}.inapp-ai-message-text ul,.inapp-ai-message-text ol{margin:8px 0;padding-left:24px}.inapp-ai-message-text li{margin:4px 0}.inapp-ai-message-text code{background:#0000000d;padding:2px 6px;border-radius:4px;font-family:Monaco,Menlo,Courier New,monospace;font-size:13px}.inapp-ai-message-text pre{background:#0000000d;padding:12px;border-radius:8px;overflow-x:auto;margin:8px 0}.inapp-ai-message-text pre code{background:none;padding:0}.inapp-ai-message-text blockquote{border-left:3px solid var(--inapp-ai-primary);padding-left:12px;margin:8px 0;color:var(--inapp-ai-text-secondary)}.inapp-ai-message-text a{color:var(--inapp-ai-primary);text-decoration:none}.inapp-ai-message-text a:hover{text-decoration:underline}.inapp-ai-message-text strong{font-weight:600}.inapp-ai-message-text em{font-style:italic}.inapp-ai-message-text hr{border:none;border-top:1px solid #dee2e6;margin:12px 0}.inapp-ai-message-text table{border-collapse:collapse;width:100%;margin:8px 0}.inapp-ai-message-text th,.inapp-ai-message-text td{border:1px solid #dee2e6;padding:6px 12px;text-align:left}.inapp-ai-message-text th{background:#00000008;font-weight:600}.inapp-ai-message-time{font-size:11px;color:#6c757d;margin-top:4px;padding:0 4px}.inapp-ai-message-tokens{opacity:.7}.inapp-ai-typing-indicator{display:flex;gap:4px;padding:12px 16px;background:#f8f9fa;border-radius:12px;width:fit-content}.inapp-ai-typing-indicator span{width:8px;height:8px;border-radius:50%;background:#6c757d;animation:typing 1.4s infinite}.inapp-ai-typing-indicator span:nth-child(2){animation-delay:.2s}.inapp-ai-typing-indicator span:nth-child(3){animation-delay:.4s}@keyframes typing{0%,60%,to{transform:translateY(0);opacity:.7}30%{transform:translateY(-10px);opacity:1}}.inapp-ai-input-area{padding:16px 20px;border-top:1px solid var(--inapp-ai-border-light);background:var(--inapp-ai-bg-primary);border-radius:0 0 var(--inapp-ai-border-radius-lg) var(--inapp-ai-border-radius-lg);flex-shrink:0}.inapp-ai-sidebar .inapp-ai-input-area{border-radius:0}.inapp-ai-panel .inapp-ai-input-area{border-radius:0;padding:12px 20px 8px}.inapp-ai-clear-btn{width:100%;padding:8px 12px;background:var(--inapp-ai-bg-secondary);border:none;border-radius:var(--inapp-ai-border-radius-sm);font-size:13px;color:var(--inapp-ai-text-secondary);cursor:pointer;margin-bottom:12px;transition:var(--inapp-ai-transition-fast)}.inapp-ai-clear-btn:hover:not(:disabled){background:var(--inapp-ai-bg-tertiary)}.inapp-ai-clear-btn:disabled{opacity:.5;cursor:not-allowed}.inapp-ai-input-wrapper{display:flex;gap:8px}.inapp-ai-input{flex:1;padding:12px 16px;border:2px solid var(--inapp-ai-input-border);background:var(--inapp-ai-input-bg);color:var(--inapp-ai-input-text);border-radius:var(--inapp-ai-border-radius);font-size:14px;font-family:inherit;outline:none;transition:var(--inapp-ai-transition-fast)}.inapp-ai-input::placeholder{color:var(--inapp-ai-input-placeholder)}.inapp-ai-input:focus{border-color:var(--inapp-ai-primary)}.inapp-ai-input:disabled{background:var(--inapp-ai-bg-secondary);cursor:not-allowed}.inapp-ai-send-btn{width:44px;height:44px;border:none;background:var(--inapp-ai-button-bg);color:var(--inapp-ai-button-text);border-radius:var(--inapp-ai-border-radius);font-size:18px;cursor:pointer;transition:var(--inapp-ai-transition-fast);display:flex;align-items:center;justify-content:center}.inapp-ai-send-btn:hover:not(:disabled){transform:translateY(-2px);box-shadow:var(--inapp-ai-shadow-md)}.inapp-ai-send-btn:disabled{opacity:.5;cursor:not-allowed}.inapp-ai-theme-dark .inapp-ai-messages::-webkit-scrollbar-track{background:#2d2d2d}.inapp-ai-theme-dark .inapp-ai-messages::-webkit-scrollbar-thumb{background:#555}.inapp-ai-theme-dark .inapp-ai-message-text{background:#2d2d2d;color:#fff}.inapp-ai-theme-dark .inapp-ai-message-text code,.inapp-ai-theme-dark .inapp-ai-message-text pre{background:#ffffff1a}.inapp-ai-theme-dark .inapp-ai-message-text blockquote{color:#aaa}.inapp-ai-theme-dark .inapp-ai-message-text th,.inapp-ai-theme-dark .inapp-ai-message-text td{border-color:#3e3e3e}.inapp-ai-theme-dark .inapp-ai-message-text th{background:#ffffff0d}.inapp-ai-theme-dark .inapp-ai-message-text hr{border-top-color:#3e3e3e}.inapp-ai-theme-dark .inapp-ai-input-area{background:#1e1e1e;border-top-color:#2d2d2d}.inapp-ai-theme-dark .inapp-ai-input{background:#2d2d2d;border-color:#3e3e3e;color:#fff}.inapp-ai-theme-dark .inapp-ai-clear-btn{background:#2d2d2d;color:#a0a0a0}.inapp-ai-theme-dark .inapp-ai-typing-indicator{background:#2d2d2d}.inapp-ai-theme-dark .inapp-ai-folded-text{color:#667eea}@media(max-width:768px){.inapp-ai-sidebar{width:100vw}.inapp-ai-sidebar.inapp-ai-folded{width:50px}.inapp-ai-popup{width:calc(100vw - 40px);height:calc(100vh - 140px)}.inapp-ai-button{width:50px;height:50px;font-size:20px}}@media(min-width:769px)and (max-width:1024px){.inapp-ai-sidebar{width:350px}}
|
|
2
|
+
/*# sourceMappingURL=index.css.map */
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/themes.css","../src/components/InAppAI.css"],"sourcesContent":["/* InAppAI Theme System - CSS Custom Properties */\n\n/* =====================================================\n BASE THEME VARIABLES\n ===================================================== */\n\n:root {\n /* Primary Colors */\n --inapp-ai-primary: #667eea;\n --inapp-ai-primary-dark: #764ba2;\n --inapp-ai-primary-gradient: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n\n /* Background Colors */\n --inapp-ai-bg-primary: #ffffff;\n --inapp-ai-bg-secondary: #f8f9fa;\n --inapp-ai-bg-tertiary: #e9ecef;\n\n /* Text Colors */\n --inapp-ai-text-primary: #333333;\n --inapp-ai-text-secondary: #666666;\n --inapp-ai-text-tertiary: #999999;\n --inapp-ai-text-inverse: #ffffff;\n\n /* Border Colors */\n --inapp-ai-border-light: #e0e0e0;\n --inapp-ai-border-medium: #cccccc;\n --inapp-ai-border-dark: #999999;\n\n /* Message Colors */\n --inapp-ai-user-bg: #667eea;\n --inapp-ai-user-text: #ffffff;\n --inapp-ai-assistant-bg: #f0f2f5;\n --inapp-ai-assistant-text: #333333;\n\n /* Input Colors */\n --inapp-ai-input-bg: #ffffff;\n --inapp-ai-input-border: #e0e0e0;\n --inapp-ai-input-text: #333333;\n --inapp-ai-input-placeholder: #999999;\n\n /* Button Colors */\n --inapp-ai-button-bg: var(--inapp-ai-primary-gradient);\n --inapp-ai-button-text: #ffffff;\n --inapp-ai-button-hover-scale: 1.1;\n\n /* Shadow */\n --inapp-ai-shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.1);\n --inapp-ai-shadow-md: 0 4px 12px rgba(0, 0, 0, 0.15);\n --inapp-ai-shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.2);\n\n /* Borders & Radius */\n --inapp-ai-border-radius: 12px;\n --inapp-ai-border-radius-sm: 8px;\n --inapp-ai-border-radius-lg: 16px;\n\n /* Transitions */\n --inapp-ai-transition: all 0.3s ease;\n --inapp-ai-transition-fast: all 0.15s ease;\n}\n\n/* =====================================================\n DARK THEME\n ===================================================== */\n\n.inapp-ai-theme-dark {\n /* Background Colors */\n --inapp-ai-bg-primary: #1a1a1a;\n --inapp-ai-bg-secondary: #2d2d2d;\n --inapp-ai-bg-tertiary: #404040;\n\n /* Text Colors */\n --inapp-ai-text-primary: #ffffff;\n --inapp-ai-text-secondary: #cccccc;\n --inapp-ai-text-tertiary: #999999;\n\n /* Border Colors */\n --inapp-ai-border-light: #404040;\n --inapp-ai-border-medium: #555555;\n --inapp-ai-border-dark: #666666;\n\n /* Message Colors */\n --inapp-ai-user-bg: #667eea;\n --inapp-ai-user-text: #ffffff;\n --inapp-ai-assistant-bg: #2d2d2d;\n --inapp-ai-assistant-text: #ffffff;\n\n /* Input Colors */\n --inapp-ai-input-bg: #2d2d2d;\n --inapp-ai-input-border: #404040;\n --inapp-ai-input-text: #ffffff;\n --inapp-ai-input-placeholder: #999999;\n\n /* Shadow */\n --inapp-ai-shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.3);\n --inapp-ai-shadow-md: 0 4px 12px rgba(0, 0, 0, 0.4);\n --inapp-ai-shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.5);\n}\n\n/* =====================================================\n PROFESSIONAL THEME\n ===================================================== */\n\n.inapp-ai-theme-professional {\n /* Primary Colors - Corporate Blue */\n --inapp-ai-primary: #0052cc;\n --inapp-ai-primary-dark: #003d99;\n --inapp-ai-primary-gradient: linear-gradient(135deg, #0052cc 0%, #003d99 100%);\n\n /* Background Colors - Clean whites and grays */\n --inapp-ai-bg-primary: #ffffff;\n --inapp-ai-bg-secondary: #f7f8f9;\n --inapp-ai-bg-tertiary: #ebecf0;\n\n /* Text Colors - Professional gray tones */\n --inapp-ai-text-primary: #172b4d;\n --inapp-ai-text-secondary: #5e6c84;\n --inapp-ai-text-tertiary: #8993a4;\n\n /* Message Colors */\n --inapp-ai-user-bg: #0052cc;\n --inapp-ai-user-text: #ffffff;\n --inapp-ai-assistant-bg: #f7f8f9;\n --inapp-ai-assistant-text: #172b4d;\n\n /* Borders */\n --inapp-ai-border-light: #dfe1e6;\n --inapp-ai-border-medium: #c1c7d0;\n --inapp-ai-border-radius: 8px;\n}\n\n/* =====================================================\n PLAYFUL THEME\n ===================================================== */\n\n.inapp-ai-theme-playful {\n /* Primary Colors - Vibrant gradient */\n --inapp-ai-primary: #ff6b6b;\n --inapp-ai-primary-dark: #ee5a6f;\n --inapp-ai-primary-gradient: linear-gradient(135deg, #ff6b6b 0%, #f06595 50%, #cc5de8 100%);\n\n /* Background Colors - Soft pastels */\n --inapp-ai-bg-primary: #fff5f7;\n --inapp-ai-bg-secondary: #ffe3e3;\n --inapp-ai-bg-tertiary: #ffd4e5;\n\n /* Text Colors - Warm tones */\n --inapp-ai-text-primary: #2d0b3d;\n --inapp-ai-text-secondary: #5a1e72;\n --inapp-ai-text-tertiary: #8b4896;\n\n /* Message Colors */\n --inapp-ai-user-bg: linear-gradient(135deg, #ff6b6b 0%, #f06595 100%);\n --inapp-ai-user-text: #ffffff;\n --inapp-ai-assistant-bg: #ffe3e3;\n --inapp-ai-assistant-text: #2d0b3d;\n\n /* Borders - Softer, rounder */\n --inapp-ai-border-radius: 20px;\n --inapp-ai-border-radius-lg: 24px;\n --inapp-ai-border-light: #ffc6d9;\n}\n\n/* =====================================================\n MINIMAL THEME\n ===================================================== */\n\n.inapp-ai-theme-minimal {\n /* Primary Colors - Monochrome */\n --inapp-ai-primary: #000000;\n --inapp-ai-primary-dark: #1a1a1a;\n --inapp-ai-primary-gradient: linear-gradient(135deg, #000000 0%, #333333 100%);\n\n /* Background Colors - Pure whites and grays */\n --inapp-ai-bg-primary: #ffffff;\n --inapp-ai-bg-secondary: #fafafa;\n --inapp-ai-bg-tertiary: #f5f5f5;\n\n /* Text Colors - Black and grays */\n --inapp-ai-text-primary: #000000;\n --inapp-ai-text-secondary: #333333;\n --inapp-ai-text-tertiary: #666666;\n\n /* Message Colors */\n --inapp-ai-user-bg: #000000;\n --inapp-ai-user-text: #ffffff;\n --inapp-ai-assistant-bg: #fafafa;\n --inapp-ai-assistant-text: #000000;\n\n /* Borders - Sharp, clean */\n --inapp-ai-border-light: #e0e0e0;\n --inapp-ai-border-medium: #cccccc;\n --inapp-ai-border-radius: 4px;\n --inapp-ai-border-radius-sm: 2px;\n --inapp-ai-border-radius-lg: 6px;\n\n /* Shadows - Subtle */\n --inapp-ai-shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.08);\n --inapp-ai-shadow-md: 0 2px 6px rgba(0, 0, 0, 0.1);\n --inapp-ai-shadow-lg: 0 4px 12px rgba(0, 0, 0, 0.12);\n}\n\n/* =====================================================\n OCEAN THEME\n ===================================================== */\n\n.inapp-ai-theme-ocean {\n /* Primary Colors - Deep ocean blues */\n --inapp-ai-primary: #0077be;\n --inapp-ai-primary-dark: #005a8d;\n --inapp-ai-primary-gradient: linear-gradient(135deg, #0077be 0%, #0096d6 100%);\n\n /* Background Colors - Water-inspired */\n --inapp-ai-bg-primary: #f0f8ff;\n --inapp-ai-bg-secondary: #e6f3ff;\n --inapp-ai-bg-tertiary: #cce7ff;\n\n /* Text Colors */\n --inapp-ai-text-primary: #003d5c;\n --inapp-ai-text-secondary: #005a8d;\n --inapp-ai-text-tertiary: #0077be;\n\n /* Message Colors */\n --inapp-ai-user-bg: #0077be;\n --inapp-ai-user-text: #ffffff;\n --inapp-ai-assistant-bg: #e6f3ff;\n --inapp-ai-assistant-text: #003d5c;\n}\n\n/* =====================================================\n SUNSET THEME\n ===================================================== */\n\n.inapp-ai-theme-sunset {\n /* Primary Colors - Warm sunset colors */\n --inapp-ai-primary: #ff6b35;\n --inapp-ai-primary-dark: #f7931e;\n --inapp-ai-primary-gradient: linear-gradient(135deg, #ff6b35 0%, #f7931e 50%, #ffc947 100%);\n\n /* Background Colors - Warm tones */\n --inapp-ai-bg-primary: #fff8f3;\n --inapp-ai-bg-secondary: #ffe8d6;\n --inapp-ai-bg-tertiary: #ffd4b8;\n\n /* Text Colors */\n --inapp-ai-text-primary: #5c2400;\n --inapp-ai-text-secondary: #8b3a00;\n --inapp-ai-text-tertiary: #b85000;\n\n /* Message Colors */\n --inapp-ai-user-bg: linear-gradient(135deg, #ff6b35 0%, #f7931e 100%);\n --inapp-ai-user-text: #ffffff;\n --inapp-ai-assistant-bg: #ffe8d6;\n --inapp-ai-assistant-text: #5c2400;\n}\n","/* InAppAI Enhanced Component Styles - Popup + Sidebar Support */\n\n/* ===== ACCESSIBILITY ===== */\n.sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border-width: 0;\n}\n\n/* ===== COMMON STYLES ===== */\n.inapp-ai-button {\n position: fixed;\n width: 60px;\n height: 60px;\n border-radius: 50%;\n border: none;\n background: var(--inapp-ai-button-bg);\n color: var(--inapp-ai-button-text);\n font-size: 24px;\n cursor: pointer;\n box-shadow: var(--inapp-ai-shadow-md);\n transition: var(--inapp-ai-transition);\n z-index: 10001;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.inapp-ai-button:hover {\n transform: scale(var(--inapp-ai-button-hover-scale));\n box-shadow: var(--inapp-ai-shadow-lg);\n}\n\n.inapp-ai-button:active {\n transform: scale(0.95);\n}\n\n.inapp-ai-offline-indicator {\n position: absolute;\n top: 8px;\n right: 8px;\n width: 12px;\n height: 12px;\n background: #dc3545;\n border-radius: 50%;\n border: 2px solid white;\n}\n\n/* ===== POSITION CLASSES FOR POPUP ===== */\n.inapp-ai-bottom-right {\n bottom: 20px;\n right: 20px;\n}\n\n.inapp-ai-bottom-left {\n bottom: 20px;\n left: 20px;\n}\n\n.inapp-ai-top-right {\n top: 20px;\n right: 20px;\n}\n\n.inapp-ai-top-left {\n top: 20px;\n left: 20px;\n}\n\n/* ===== CHAT WINDOW BASE ===== */\n.inapp-ai-window {\n position: fixed;\n background: var(--inapp-ai-bg-primary);\n box-shadow: var(--inapp-ai-shadow-lg);\n display: flex;\n flex-direction: column;\n z-index: 10000;\n transition: var(--inapp-ai-transition);\n}\n\n/* ===== POPUP MODE ===== */\n.inapp-ai-popup {\n width: 380px;\n max-width: calc(100vw - 40px);\n height: 600px;\n max-height: calc(100vh - 100px);\n border-radius: var(--inapp-ai-border-radius-lg);\n animation: slideUp 0.3s ease-out;\n}\n\n.inapp-ai-popup.inapp-ai-bottom-right {\n bottom: 100px;\n right: 20px;\n}\n\n.inapp-ai-popup.inapp-ai-bottom-left {\n bottom: 100px;\n left: 20px;\n}\n\n.inapp-ai-popup.inapp-ai-top-right {\n top: 100px;\n right: 20px;\n}\n\n.inapp-ai-popup.inapp-ai-top-left {\n top: 100px;\n left: 20px;\n}\n\n@keyframes slideUp {\n from {\n opacity: 0;\n transform: translateY(20px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n/* ===== SIDEBAR MODE ===== */\n.inapp-ai-sidebar {\n top: 30px;\n height: calc(100vh - 60px);\n width: 400px;\n max-width: 100vw;\n border-radius: 0;\n animation: slideIn 0.3s ease-out;\n}\n\n.inapp-ai-sidebar-left {\n left: 0;\n border-right: 1px solid var(--inapp-ai-border-light);\n box-shadow: 8px 0 32px rgba(0, 0, 0, 0.12);\n}\n\n.inapp-ai-sidebar-right {\n right: 0;\n border-left: 1px solid var(--inapp-ai-border-light);\n box-shadow: -8px 0 32px rgba(0, 0, 0, 0.12);\n}\n\n/* Folded Sidebar */\n.inapp-ai-sidebar.inapp-ai-folded {\n width: 60px;\n}\n\n@keyframes slideIn {\n from {\n opacity: 0;\n transform: translateX(-20px);\n }\n to {\n opacity: 1;\n transform: translateX(0);\n }\n}\n\n.inapp-ai-sidebar-right:not(.inapp-ai-folded) {\n animation-name: slideInRight;\n}\n\n@keyframes slideInRight {\n from {\n opacity: 0;\n transform: translateX(20px);\n }\n to {\n opacity: 1;\n transform: translateX(0);\n }\n}\n\n/* ===== FOLD/UNFOLD TOGGLE ===== */\n.inapp-ai-fold-toggle {\n position: absolute;\n top: 50%;\n transform: translateY(-50%);\n width: 32px;\n height: 64px;\n background: var(--inapp-ai-primary-gradient);\n color: var(--inapp-ai-text-inverse);\n border: none;\n cursor: pointer;\n font-size: 16px;\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 10;\n transition: var(--inapp-ai-transition-fast);\n box-shadow: var(--inapp-ai-shadow-sm);\n}\n\n.inapp-ai-sidebar-left .inapp-ai-fold-toggle {\n right: -16px;\n border-radius: 0 var(--inapp-ai-border-radius-sm) var(--inapp-ai-border-radius-sm) 0;\n}\n\n.inapp-ai-sidebar-right .inapp-ai-fold-toggle {\n left: -16px;\n border-radius: var(--inapp-ai-border-radius-sm) 0 0 var(--inapp-ai-border-radius-sm);\n}\n\n.inapp-ai-fold-toggle:hover {\n background: var(--inapp-ai-primary-dark);\n transform: translateY(-50%) scale(1.05);\n}\n\n.inapp-ai-fold-toggle:active {\n transform: translateY(-50%) scale(0.95);\n}\n\n/* ===== FOLDED CONTENT ===== */\n.inapp-ai-folded-content {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 20px 0;\n height: 100%;\n gap: 16px;\n}\n\n.inapp-ai-folded-icon {\n font-size: 32px;\n margin-top: 20px;\n animation: pulse 2s infinite;\n}\n\n.inapp-ai-folded-text {\n display: none;\n}\n\n.inapp-ai-message-count {\n background: var(--inapp-ai-primary-gradient);\n color: var(--inapp-ai-text-inverse);\n width: 24px;\n height: 24px;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 12px;\n font-weight: 600;\n margin-top: 8px;\n animation: bounce 0.5s ease-out;\n}\n\n@keyframes bounce {\n 0%, 100% { transform: scale(1); }\n 50% { transform: scale(1.2); }\n}\n\n/* ===== PANEL MODE ===== */\n.inapp-ai-panel {\n position: relative;\n top: 0;\n height: 100vh;\n min-height: 100vh;\n max-height: 100vh;\n border-radius: 0;\n box-shadow: none;\n display: flex;\n flex-direction: column;\n}\n\n.inapp-ai-panel-left {\n left: 0;\n border-right: 1px solid var(--inapp-ai-border-light);\n}\n\n.inapp-ai-panel-right {\n right: 0;\n border-left: 1px solid var(--inapp-ai-border-light);\n}\n\n/* Panel Resize Handle */\n.inapp-ai-resize-handle {\n position: absolute;\n top: 0;\n width: 6px;\n height: 100%;\n background: transparent;\n cursor: col-resize;\n z-index: 11;\n transition: background 0.2s;\n}\n\n.inapp-ai-resize-handle:hover {\n background: rgba(102, 126, 234, 0.3);\n}\n\n.inapp-ai-resize-handle:active {\n background: rgba(102, 126, 234, 0.5);\n}\n\n.inapp-ai-resize-handle-right {\n right: 0;\n border-right: 2px solid transparent;\n}\n\n.inapp-ai-resize-handle-left {\n left: 0;\n border-left: 2px solid transparent;\n}\n\n.inapp-ai-resize-handle-right:hover,\n.inapp-ai-resize-handle-right:active {\n border-right-color: var(--inapp-ai-primary);\n}\n\n.inapp-ai-resize-handle-left:hover,\n.inapp-ai-resize-handle-left:active {\n border-left-color: var(--inapp-ai-primary);\n}\n\n.inapp-ai-panel .inapp-ai-header {\n border-radius: 0;\n}\n\n/* Folded Panel */\n.inapp-ai-panel.inapp-ai-folded {\n width: 60px;\n min-width: 60px;\n max-width: 60px;\n}\n\n/* ===== THEME - DARK ===== */\n.inapp-ai-window.inapp-ai-theme-dark {\n background: #1e1e1e;\n color: #ffffff;\n}\n\n.inapp-ai-sidebar-left.inapp-ai-theme-dark {\n border-right-color: #2d2d2d;\n}\n\n.inapp-ai-sidebar-right.inapp-ai-theme-dark {\n border-left-color: #2d2d2d;\n}\n\n/* ===== HEADER ===== */\n.inapp-ai-header {\n padding: 20px;\n background: var(--inapp-ai-primary-gradient);\n color: var(--inapp-ai-text-inverse);\n border-radius: var(--inapp-ai-border-radius-lg) var(--inapp-ai-border-radius-lg) 0 0;\n display: flex;\n justify-content: space-between;\n align-items: center;\n flex-shrink: 0;\n}\n\n.inapp-ai-sidebar .inapp-ai-header {\n border-radius: 0;\n}\n\n.inapp-ai-header-title {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.inapp-ai-header-icon {\n font-size: 32px;\n}\n\n.inapp-ai-header h3 {\n margin: 0;\n font-size: 18px;\n font-weight: 600;\n}\n\n.inapp-ai-header p {\n margin: 4px 0 0 0;\n font-size: 12px;\n opacity: 0.9;\n}\n\n.inapp-ai-status-connected,\n.inapp-ai-status-disconnected {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.inapp-ai-status-dot {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n background: #28a745;\n animation: pulse 2s infinite;\n}\n\n.inapp-ai-status-disconnected .inapp-ai-status-dot {\n background: #dc3545;\n}\n\n@keyframes pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.5; }\n}\n\n.inapp-ai-close-btn {\n background: rgba(255, 255, 255, 0.2);\n border: none;\n color: white;\n width: 32px;\n height: 32px;\n border-radius: 8px;\n cursor: pointer;\n font-size: 18px;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: background 0.2s;\n}\n\n.inapp-ai-close-btn:hover {\n background: rgba(255, 255, 255, 0.3);\n}\n\n/* Header Fold Button (for sidebars and panels) */\n.inapp-ai-header-fold-btn {\n background: rgba(255, 255, 255, 0.2);\n border: none;\n color: white;\n width: 32px;\n height: 32px;\n border-radius: 8px;\n cursor: pointer;\n font-size: 16px;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: background 0.2s;\n}\n\n.inapp-ai-header-fold-btn:hover {\n background: rgba(255, 255, 255, 0.3);\n}\n\n/* ===== ERROR BANNER ===== */\n.inapp-ai-error-banner {\n padding: 12px 20px;\n background: #fff3cd;\n color: #856404;\n display: flex;\n align-items: center;\n gap: 10px;\n font-size: 14px;\n border-bottom: 1px solid #ffeeba;\n flex-shrink: 0;\n}\n\n.inapp-ai-error-banner button {\n margin-left: auto;\n background: none;\n border: none;\n color: #856404;\n cursor: pointer;\n padding: 4px 8px;\n}\n\n/* ===== MESSAGES AREA ===== */\n.inapp-ai-messages {\n flex: 1;\n overflow-y: auto;\n padding: 20px;\n display: flex;\n flex-direction: column;\n gap: 16px;\n min-height: 0; /* Important for flex scrolling */\n}\n\n.inapp-ai-messages::-webkit-scrollbar {\n width: 8px;\n}\n\n.inapp-ai-messages::-webkit-scrollbar-track {\n background: #f1f1f1;\n}\n\n.inapp-ai-messages::-webkit-scrollbar-thumb {\n background: #c1c1c1;\n border-radius: 4px;\n}\n\n.inapp-ai-messages::-webkit-scrollbar-thumb:hover {\n background: #a1a1a1;\n}\n\n/* Empty State */\n.inapp-ai-empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n text-align: center;\n color: #6c757d;\n padding: 40px;\n}\n\n.inapp-ai-empty-icon {\n font-size: 48px;\n margin-bottom: 16px;\n}\n\n.inapp-ai-empty-state h4 {\n margin: 0 0 8px 0;\n font-size: 18px;\n color: #495057;\n}\n\n.inapp-ai-empty-state p {\n margin: 0;\n font-size: 14px;\n}\n\n/* Message */\n.inapp-ai-message {\n display: flex;\n gap: 12px;\n animation: messageSlideIn 0.3s ease-out;\n}\n\n@keyframes messageSlideIn {\n from {\n opacity: 0;\n transform: translateY(10px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n.inapp-ai-message-user {\n flex-direction: row-reverse;\n}\n\n.inapp-ai-message-icon {\n width: 36px;\n height: 36px;\n border-radius: 50%;\n background: var(--inapp-ai-bg-secondary);\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 20px;\n flex-shrink: 0;\n}\n\n.inapp-ai-message-user .inapp-ai-message-icon {\n background: var(--inapp-ai-primary-gradient);\n}\n\n.inapp-ai-message-assistant .inapp-ai-message-icon {\n background: var(--inapp-ai-primary-gradient);\n}\n\n.inapp-ai-message-content {\n flex: 1;\n min-width: 0;\n}\n\n.inapp-ai-message-text {\n background: var(--inapp-ai-assistant-bg);\n color: var(--inapp-ai-assistant-text);\n padding: 12px 16px;\n border-radius: var(--inapp-ai-border-radius);\n line-height: 1.5;\n font-size: 14px;\n word-wrap: break-word;\n}\n\n.inapp-ai-message-user .inapp-ai-message-text {\n background: var(--inapp-ai-user-bg);\n color: var(--inapp-ai-user-text);\n border-radius: var(--inapp-ai-border-radius) var(--inapp-ai-border-radius) var(--inapp-ai-border-radius-sm) var(--inapp-ai-border-radius);\n}\n\n.inapp-ai-message-assistant .inapp-ai-message-text {\n border-radius: var(--inapp-ai-border-radius) var(--inapp-ai-border-radius) var(--inapp-ai-border-radius) var(--inapp-ai-border-radius-sm);\n}\n\n/* Markdown Styling */\n.inapp-ai-message-text p {\n margin: 0 0 8px 0;\n}\n\n.inapp-ai-message-text p:last-child {\n margin-bottom: 0;\n}\n\n.inapp-ai-message-text h1,\n.inapp-ai-message-text h2,\n.inapp-ai-message-text h3,\n.inapp-ai-message-text h4 {\n margin: 12px 0 8px 0;\n font-weight: 600;\n}\n\n.inapp-ai-message-text h1:first-child,\n.inapp-ai-message-text h2:first-child,\n.inapp-ai-message-text h3:first-child,\n.inapp-ai-message-text h4:first-child {\n margin-top: 0;\n}\n\n.inapp-ai-message-text h1 { font-size: 18px; }\n.inapp-ai-message-text h2 { font-size: 16px; }\n.inapp-ai-message-text h3 { font-size: 15px; }\n.inapp-ai-message-text h4 { font-size: 14px; }\n\n.inapp-ai-message-text ul,\n.inapp-ai-message-text ol {\n margin: 8px 0;\n padding-left: 24px;\n}\n\n.inapp-ai-message-text li {\n margin: 4px 0;\n}\n\n.inapp-ai-message-text code {\n background: rgba(0, 0, 0, 0.05);\n padding: 2px 6px;\n border-radius: 4px;\n font-family: 'Monaco', 'Menlo', 'Courier New', monospace;\n font-size: 13px;\n}\n\n.inapp-ai-message-text pre {\n background: rgba(0, 0, 0, 0.05);\n padding: 12px;\n border-radius: 8px;\n overflow-x: auto;\n margin: 8px 0;\n}\n\n.inapp-ai-message-text pre code {\n background: none;\n padding: 0;\n}\n\n.inapp-ai-message-text blockquote {\n border-left: 3px solid var(--inapp-ai-primary);\n padding-left: 12px;\n margin: 8px 0;\n color: var(--inapp-ai-text-secondary);\n}\n\n.inapp-ai-message-text a {\n color: var(--inapp-ai-primary);\n text-decoration: none;\n}\n\n.inapp-ai-message-text a:hover {\n text-decoration: underline;\n}\n\n.inapp-ai-message-text strong { font-weight: 600; }\n.inapp-ai-message-text em { font-style: italic; }\n\n.inapp-ai-message-text hr {\n border: none;\n border-top: 1px solid #dee2e6;\n margin: 12px 0;\n}\n\n.inapp-ai-message-text table {\n border-collapse: collapse;\n width: 100%;\n margin: 8px 0;\n}\n\n.inapp-ai-message-text th,\n.inapp-ai-message-text td {\n border: 1px solid #dee2e6;\n padding: 6px 12px;\n text-align: left;\n}\n\n.inapp-ai-message-text th {\n background: rgba(0, 0, 0, 0.03);\n font-weight: 600;\n}\n\n.inapp-ai-message-time {\n font-size: 11px;\n color: #6c757d;\n margin-top: 4px;\n padding: 0 4px;\n}\n\n.inapp-ai-message-tokens {\n opacity: 0.7;\n}\n\n/* Typing Indicator */\n.inapp-ai-typing-indicator {\n display: flex;\n gap: 4px;\n padding: 12px 16px;\n background: #f8f9fa;\n border-radius: 12px;\n width: fit-content;\n}\n\n.inapp-ai-typing-indicator span {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n background: #6c757d;\n animation: typing 1.4s infinite;\n}\n\n.inapp-ai-typing-indicator span:nth-child(2) { animation-delay: 0.2s; }\n.inapp-ai-typing-indicator span:nth-child(3) { animation-delay: 0.4s; }\n\n@keyframes typing {\n 0%, 60%, 100% {\n transform: translateY(0);\n opacity: 0.7;\n }\n 30% {\n transform: translateY(-10px);\n opacity: 1;\n }\n}\n\n/* ===== INPUT AREA ===== */\n.inapp-ai-input-area {\n padding: 16px 20px;\n border-top: 1px solid var(--inapp-ai-border-light);\n background: var(--inapp-ai-bg-primary);\n border-radius: 0 0 var(--inapp-ai-border-radius-lg) var(--inapp-ai-border-radius-lg);\n flex-shrink: 0;\n}\n\n.inapp-ai-sidebar .inapp-ai-input-area {\n border-radius: 0;\n}\n\n.inapp-ai-panel .inapp-ai-input-area {\n border-radius: 0;\n padding: 12px 20px 8px 20px;\n}\n\n.inapp-ai-clear-btn {\n width: 100%;\n padding: 8px 12px;\n background: var(--inapp-ai-bg-secondary);\n border: none;\n border-radius: var(--inapp-ai-border-radius-sm);\n font-size: 13px;\n color: var(--inapp-ai-text-secondary);\n cursor: pointer;\n margin-bottom: 12px;\n transition: var(--inapp-ai-transition-fast);\n}\n\n.inapp-ai-clear-btn:hover:not(:disabled) {\n background: var(--inapp-ai-bg-tertiary);\n}\n\n.inapp-ai-clear-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.inapp-ai-input-wrapper {\n display: flex;\n gap: 8px;\n}\n\n.inapp-ai-input {\n flex: 1;\n padding: 12px 16px;\n border: 2px solid var(--inapp-ai-input-border);\n background: var(--inapp-ai-input-bg);\n color: var(--inapp-ai-input-text);\n border-radius: var(--inapp-ai-border-radius);\n font-size: 14px;\n font-family: inherit;\n outline: none;\n transition: var(--inapp-ai-transition-fast);\n}\n\n.inapp-ai-input::placeholder {\n color: var(--inapp-ai-input-placeholder);\n}\n\n.inapp-ai-input:focus {\n border-color: var(--inapp-ai-primary);\n}\n\n.inapp-ai-input:disabled {\n background: var(--inapp-ai-bg-secondary);\n cursor: not-allowed;\n}\n\n.inapp-ai-send-btn {\n width: 44px;\n height: 44px;\n border: none;\n background: var(--inapp-ai-button-bg);\n color: var(--inapp-ai-button-text);\n border-radius: var(--inapp-ai-border-radius);\n font-size: 18px;\n cursor: pointer;\n transition: var(--inapp-ai-transition-fast);\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.inapp-ai-send-btn:hover:not(:disabled) {\n transform: translateY(-2px);\n box-shadow: var(--inapp-ai-shadow-md);\n}\n\n.inapp-ai-send-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n/* ===== DARK THEME ADJUSTMENTS ===== */\n.inapp-ai-theme-dark .inapp-ai-messages::-webkit-scrollbar-track {\n background: #2d2d2d;\n}\n\n.inapp-ai-theme-dark .inapp-ai-messages::-webkit-scrollbar-thumb {\n background: #555;\n}\n\n.inapp-ai-theme-dark .inapp-ai-message-text {\n background: #2d2d2d;\n color: #ffffff;\n}\n\n.inapp-ai-theme-dark .inapp-ai-message-text code {\n background: rgba(255, 255, 255, 0.1);\n}\n\n.inapp-ai-theme-dark .inapp-ai-message-text pre {\n background: rgba(255, 255, 255, 0.1);\n}\n\n.inapp-ai-theme-dark .inapp-ai-message-text blockquote {\n color: #aaa;\n}\n\n.inapp-ai-theme-dark .inapp-ai-message-text th,\n.inapp-ai-theme-dark .inapp-ai-message-text td {\n border-color: #3e3e3e;\n}\n\n.inapp-ai-theme-dark .inapp-ai-message-text th {\n background: rgba(255, 255, 255, 0.05);\n}\n\n.inapp-ai-theme-dark .inapp-ai-message-text hr {\n border-top-color: #3e3e3e;\n}\n\n.inapp-ai-theme-dark .inapp-ai-input-area {\n background: #1e1e1e;\n border-top-color: #2d2d2d;\n}\n\n.inapp-ai-theme-dark .inapp-ai-input {\n background: #2d2d2d;\n border-color: #3e3e3e;\n color: #ffffff;\n}\n\n.inapp-ai-theme-dark .inapp-ai-clear-btn {\n background: #2d2d2d;\n color: #a0a0a0;\n}\n\n.inapp-ai-theme-dark .inapp-ai-typing-indicator {\n background: #2d2d2d;\n}\n\n.inapp-ai-theme-dark .inapp-ai-folded-text {\n color: #667eea;\n}\n\n/* ===== RESPONSIVE ===== */\n@media (max-width: 768px) {\n .inapp-ai-sidebar {\n width: 100vw;\n }\n\n .inapp-ai-sidebar.inapp-ai-folded {\n width: 50px;\n }\n\n .inapp-ai-popup {\n width: calc(100vw - 40px);\n height: calc(100vh - 140px);\n }\n\n .inapp-ai-button {\n width: 50px;\n height: 50px;\n font-size: 20px;\n }\n}\n\n@media (min-width: 769px) and (max-width: 1024px) {\n .inapp-ai-sidebar {\n width: 350px;\n }\n}\n"],"mappings":"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","names":[]}
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
|
|
3
|
+
interface CustomStyles {
|
|
4
|
+
primaryColor?: string;
|
|
5
|
+
primaryGradient?: string;
|
|
6
|
+
buttonBackgroundColor?: string;
|
|
7
|
+
buttonTextColor?: string;
|
|
8
|
+
buttonSize?: string;
|
|
9
|
+
buttonBorderRadius?: string;
|
|
10
|
+
buttonIcon?: string;
|
|
11
|
+
windowWidth?: string;
|
|
12
|
+
windowHeight?: string;
|
|
13
|
+
windowBorderRadius?: string;
|
|
14
|
+
headerBackground?: string;
|
|
15
|
+
headerTextColor?: string;
|
|
16
|
+
headerTitle?: string;
|
|
17
|
+
headerSubtitle?: string;
|
|
18
|
+
userMessageBackground?: string;
|
|
19
|
+
userMessageColor?: string;
|
|
20
|
+
assistantMessageBackground?: string;
|
|
21
|
+
assistantMessageColor?: string;
|
|
22
|
+
fontFamily?: string;
|
|
23
|
+
fontSize?: string;
|
|
24
|
+
inputBackground?: string;
|
|
25
|
+
inputBorderColor?: string;
|
|
26
|
+
inputTextColor?: string;
|
|
27
|
+
inputPlaceholder?: string;
|
|
28
|
+
sidebarWidth?: string;
|
|
29
|
+
sidebarFoldedWidth?: string;
|
|
30
|
+
borderRadius?: string;
|
|
31
|
+
boxShadow?: string;
|
|
32
|
+
}
|
|
33
|
+
interface Tool {
|
|
34
|
+
name: string;
|
|
35
|
+
description: string;
|
|
36
|
+
parameters: any;
|
|
37
|
+
handler: (params: any) => Promise<any> | any;
|
|
38
|
+
}
|
|
39
|
+
interface InAppAIProps {
|
|
40
|
+
endpoint: string;
|
|
41
|
+
position?: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left';
|
|
42
|
+
displayMode?: 'popup' | 'sidebar-left' | 'sidebar-right' | 'panel-left' | 'panel-right';
|
|
43
|
+
defaultFolded?: boolean;
|
|
44
|
+
theme?: 'light' | 'dark' | 'professional' | 'playful' | 'minimal' | 'ocean' | 'sunset';
|
|
45
|
+
context?: Record<string, any> | (() => Record<string, any>);
|
|
46
|
+
customStyles?: CustomStyles;
|
|
47
|
+
tools?: Tool[];
|
|
48
|
+
panelMinWidth?: string;
|
|
49
|
+
panelMaxWidth?: string;
|
|
50
|
+
panelDefaultWidth?: string;
|
|
51
|
+
onPanelResize?: (width: number) => void;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
declare function InAppAI({ endpoint, position, displayMode, defaultFolded, theme, context, customStyles, tools, panelMinWidth, panelMaxWidth, panelDefaultWidth, onPanelResize }: InAppAIProps): react_jsx_runtime.JSX.Element;
|
|
55
|
+
|
|
56
|
+
export { type CustomStyles, InAppAI, type InAppAIProps, type Tool };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
|
|
3
|
+
interface CustomStyles {
|
|
4
|
+
primaryColor?: string;
|
|
5
|
+
primaryGradient?: string;
|
|
6
|
+
buttonBackgroundColor?: string;
|
|
7
|
+
buttonTextColor?: string;
|
|
8
|
+
buttonSize?: string;
|
|
9
|
+
buttonBorderRadius?: string;
|
|
10
|
+
buttonIcon?: string;
|
|
11
|
+
windowWidth?: string;
|
|
12
|
+
windowHeight?: string;
|
|
13
|
+
windowBorderRadius?: string;
|
|
14
|
+
headerBackground?: string;
|
|
15
|
+
headerTextColor?: string;
|
|
16
|
+
headerTitle?: string;
|
|
17
|
+
headerSubtitle?: string;
|
|
18
|
+
userMessageBackground?: string;
|
|
19
|
+
userMessageColor?: string;
|
|
20
|
+
assistantMessageBackground?: string;
|
|
21
|
+
assistantMessageColor?: string;
|
|
22
|
+
fontFamily?: string;
|
|
23
|
+
fontSize?: string;
|
|
24
|
+
inputBackground?: string;
|
|
25
|
+
inputBorderColor?: string;
|
|
26
|
+
inputTextColor?: string;
|
|
27
|
+
inputPlaceholder?: string;
|
|
28
|
+
sidebarWidth?: string;
|
|
29
|
+
sidebarFoldedWidth?: string;
|
|
30
|
+
borderRadius?: string;
|
|
31
|
+
boxShadow?: string;
|
|
32
|
+
}
|
|
33
|
+
interface Tool {
|
|
34
|
+
name: string;
|
|
35
|
+
description: string;
|
|
36
|
+
parameters: any;
|
|
37
|
+
handler: (params: any) => Promise<any> | any;
|
|
38
|
+
}
|
|
39
|
+
interface InAppAIProps {
|
|
40
|
+
endpoint: string;
|
|
41
|
+
position?: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left';
|
|
42
|
+
displayMode?: 'popup' | 'sidebar-left' | 'sidebar-right' | 'panel-left' | 'panel-right';
|
|
43
|
+
defaultFolded?: boolean;
|
|
44
|
+
theme?: 'light' | 'dark' | 'professional' | 'playful' | 'minimal' | 'ocean' | 'sunset';
|
|
45
|
+
context?: Record<string, any> | (() => Record<string, any>);
|
|
46
|
+
customStyles?: CustomStyles;
|
|
47
|
+
tools?: Tool[];
|
|
48
|
+
panelMinWidth?: string;
|
|
49
|
+
panelMaxWidth?: string;
|
|
50
|
+
panelDefaultWidth?: string;
|
|
51
|
+
onPanelResize?: (width: number) => void;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
declare function InAppAI({ endpoint, position, displayMode, defaultFolded, theme, context, customStyles, tools, panelMinWidth, panelMaxWidth, panelDefaultWidth, onPanelResize }: InAppAIProps): react_jsx_runtime.JSX.Element;
|
|
55
|
+
|
|
56
|
+
export { type CustomStyles, InAppAI, type InAppAIProps, type Tool };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";var ha=Object.create;var $=Object.defineProperty;var va=Object.getOwnPropertyDescriptor;var ya=Object.getOwnPropertyNames;var ka=Object.getPrototypeOf,wa=Object.prototype.hasOwnProperty;var Ca=(n,o)=>{for(var r in o)$(n,r,{get:o[r],enumerable:!0})},ea=(n,o,r,c)=>{if(o&&typeof o=="object"||typeof o=="function")for(let p of ya(o))!wa.call(n,p)&&p!==r&&$(n,p,{get:()=>o[p],enumerable:!(c=va(o,p))||c.enumerable});return n};var Ea=(n,o,r)=>(r=n!=null?ha(ka(n)):{},ea(o||!n||!n.__esModule?$(r,"default",{value:n,enumerable:!0}):r,n)),Ia=n=>ea($({},"__esModule",{value:!0}),n);var Ma={};Ca(Ma,{InAppAI:()=>pa});module.exports=Ia(Ma);var t=require("react"),na=Ea(require("react-markdown")),ra=require("react-syntax-highlighter"),ta=require("react-syntax-highlighter/dist/esm/styles/prism");var a=require("react/jsx-runtime");function za(){return(0,a.jsxs)("div",{style:{display:"flex",flexDirection:"column",gap:"8px",padding:"12px 16px",background:"var(--inapp-ai-assistant-bg)",borderRadius:"var(--inapp-ai-border-radius)"},children:[(0,a.jsx)("div",{style:{height:"14px",background:"linear-gradient(90deg, #e0e0e0 25%, #f0f0f0 50%, #e0e0e0 75%)",backgroundSize:"200% 100%",animation:"shimmer 1.5s infinite",borderRadius:"4px"}}),(0,a.jsx)("div",{style:{height:"14px",width:"90%",background:"linear-gradient(90deg, #e0e0e0 25%, #f0f0f0 50%, #e0e0e0 75%)",backgroundSize:"200% 100%",animation:"shimmer 1.5s infinite",animationDelay:"0.1s",borderRadius:"4px"}}),(0,a.jsx)("div",{style:{height:"14px",width:"75%",background:"linear-gradient(90deg, #e0e0e0 25%, #f0f0f0 50%, #e0e0e0 75%)",backgroundSize:"200% 100%",animation:"shimmer 1.5s infinite",animationDelay:"0.2s",borderRadius:"4px"}}),(0,a.jsx)("style",{children:`
|
|
2
|
+
@keyframes shimmer {
|
|
3
|
+
0% { background-position: 200% 0; }
|
|
4
|
+
100% { background-position: -200% 0; }
|
|
5
|
+
}
|
|
6
|
+
`})]})}function Na({error:n,onDismiss:o}){let c=(p=>p.includes("not responding")||p.includes("connection")||p.includes("network")?{type:"connection",icon:"\u{1F50C}",title:"Connection Error"}:p.includes("timeout")?{type:"timeout",icon:"\u23F1\uFE0F",title:"Request Timeout"}:p.includes("rate limit")?{type:"rateLimit",icon:"\u{1F6A6}",title:"Rate Limit"}:p.includes("authentication")||p.includes("unauthorized")?{type:"auth",icon:"\u{1F512}",title:"Authentication Error"}:{type:"generic",icon:"\u26A0\uFE0F",title:"Error"})(n);return(0,a.jsxs)("div",{className:"inapp-ai-error-banner",role:"alert","aria-live":"assertive",style:{display:"flex",alignItems:"flex-start",gap:"12px",padding:"14px 16px",background:"linear-gradient(135deg, #fff3cd 0%, #ffe9a6 100%)",borderLeft:"4px solid #ff9800",borderRadius:"0"},children:[(0,a.jsx)("span",{style:{fontSize:"20px"},children:c.icon}),(0,a.jsxs)("div",{style:{flex:1,minWidth:0},children:[(0,a.jsx)("div",{style:{fontWeight:600,marginBottom:"4px",color:"#856404"},children:c.title}),(0,a.jsx)("div",{style:{fontSize:"13px",color:"#856404",wordBreak:"break-word"},children:n}),c.type==="connection"&&(0,a.jsx)("div",{style:{fontSize:"12px",marginTop:"6px",color:"#997404"},children:"\u{1F4A1} Make sure the backend server is running on the correct port"})]}),(0,a.jsx)("button",{onClick:o,style:{background:"none",border:"none",color:"#856404",cursor:"pointer",padding:"4px 8px",fontSize:"16px",lineHeight:1},"aria-label":"Dismiss error",children:"\u2715"})]})}function Ta({inline:n,className:o,children:r,...c}){let[p,m]=(0,t.useState)(!1),i=/language-(\w+)/.exec(o||""),M=i?i[1]:"",E=String(r).replace(/\n$/,""),A=()=>{navigator.clipboard.writeText(E),m(!0),setTimeout(()=>m(!1),2e3)};return n?(0,a.jsx)("code",{className:o,...c,children:r}):(0,a.jsxs)("div",{style:{position:"relative",marginTop:"8px",marginBottom:"8px"},children:[(0,a.jsx)("button",{onClick:A,style:{position:"absolute",top:"8px",right:"8px",padding:"4px 8px",background:p?"#28a745":"rgba(255, 255, 255, 0.1)",color:"white",border:"none",borderRadius:"4px",cursor:"pointer",fontSize:"12px",zIndex:1,transition:"background 0.2s"},"aria-label":"Copy code",children:p?"\u2713 Copied!":"\u{1F4CB} Copy"}),(0,a.jsx)(ra.Prism,{language:M||"text",style:ta.vscDarkPlus,customStyle:{borderRadius:"8px",padding:"16px",fontSize:"13px",marginTop:0,marginBottom:0},...c,children:E})]})}function pa({endpoint:n="http://localhost:3001",position:o="bottom-right",displayMode:r="popup",defaultFolded:c=!1,theme:p="light",context:m,customStyles:i={},tools:M=[],panelMinWidth:E="20%",panelMaxWidth:A="33.33%",panelDefaultWidth:oa="25%",onPanelResize:O}){let[I,L]=(0,t.useState)(r.startsWith("sidebar")||r.startsWith("panel")),[u,sa]=(0,t.useState)(c&&(r.startsWith("sidebar")||r.startsWith("panel"))),[h,R]=(0,t.useState)([]),[F,j]=(0,t.useState)(""),[f,Y]=(0,t.useState)(!1),[v,K]=(0,t.useState)(!1),[V,y]=(0,t.useState)(null),[da,la]=(0,t.useState)(oa),[X,J]=(0,t.useState)(!1),q=(0,t.useRef)(null),W=(0,t.useRef)(`react-demo-${Date.now()}`),G=(0,t.useRef)(null),Q=(0,t.useRef)(null),s=r.startsWith("sidebar"),d=r.startsWith("panel"),ca=r==="sidebar-left",B=r==="panel-left";(0,t.useEffect)(()=>{(s||d)&&L(!0)},[s,d]),(0,t.useEffect)(()=>{if(!d||!X)return;let e=l=>{let z=G.current?.parentElement;if(!z)return;let N=z.getBoundingClientRect(),g;B?g=l.clientX:g=N.width-l.clientX;let w=g/N.width*100,x=parseFloat(E),C=parseFloat(A),U=`${Math.max(x,Math.min(C,w))}%`;la(U),O&&O(g)},k=()=>{J(!1)};return document.addEventListener("mousemove",e),document.addEventListener("mouseup",k),()=>{document.removeEventListener("mousemove",e),document.removeEventListener("mouseup",k)}},[X,d,B,E,A,O]),(0,t.useEffect)(()=>{let e=async()=>{try{(await fetch(`${n}/health`)).ok?(K(!0),y(null)):y("Backend not responding")}catch{y("Failed to connect to backend"),K(!1)}};e();let k=setInterval(e,3e4);return()=>clearInterval(k)},[n]),(0,t.useEffect)(()=>{q.current?.scrollIntoView({behavior:"smooth"})},[h]),(0,t.useEffect)(()=>{!f&&v&&setTimeout(()=>{Q.current?.focus()},100)},[f,v]);let Z=async()=>{let e=F.trim();if(!e||f)return;let k={id:`${Date.now()}-user`,role:"user",content:e,timestamp:new Date};R(l=>[...l,k]),j(""),Y(!0),y(null);try{let l=()=>typeof m=="function"?m():m,z=M.map(({name:w,description:x,parameters:C})=>({type:"function",function:{name:w,description:x,parameters:C}})),N=await fetch(`${n}/chat`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({message:e,conversationId:W.current,context:l(),tools:z.length>0?z:void 0,disableCache:!1})});if(!N.ok)throw new Error("Failed to get response");let g=await N.json();if(g.toolCalls&&g.toolCalls.length>0){let x=(await Promise.all(g.toolCalls.map(async b=>{let P=b.function?.name||b.name,D=b.function?.arguments?JSON.parse(b.function.arguments):b.parameters,S=M.find(T=>T.name===P);if(!S)return{success:!1,error:`Tool '${P}' not found`};try{return await Promise.resolve(S.handler(D))}catch(T){return console.error(`Tool '${S.name}' failed:`,T),{success:!1,error:T.message}}}))).map((b,P)=>{let D=g.toolCalls[P];return`Tool "${D.function?.name||D.name}" result: ${JSON.stringify(b)}`}).join(`
|
|
7
|
+
`),C=await fetch(`${n}/chat`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({message:x,conversationId:W.current,context:l(),disableCache:!1})});if(!C.ok)throw new Error("Failed to get AI response for tool results");let H=await C.json(),U={id:`${Date.now()}-assistant`,role:"assistant",content:H.message||"I executed the tools successfully.",timestamp:new Date,usage:H.usage};R(b=>[...b,U])}else{let w={id:`${Date.now()}-assistant`,role:"assistant",content:g.message,timestamp:new Date,usage:g.usage};R(x=>[...x,w])}}catch(l){console.error("\u274C Error:",l),y(l instanceof Error?l.message:"Unknown error")}finally{Y(!1)}},ga=e=>{e.key==="Enter"&&!e.shiftKey&&(e.preventDefault(),Z())},fa=()=>{R([]),W.current=`react-demo-${Date.now()}`},_=()=>{sa(!u)},aa=`inapp-ai-${o}`,ia=p&&p!=="light"?`inapp-ai-theme-${p}`:"",ba=s?`inapp-ai-sidebar inapp-ai-${r}`:d?`inapp-ai-panel inapp-ai-${r}`:"inapp-ai-popup",ua=u?"inapp-ai-folded":"",xa={...i.buttonBackgroundColor&&{background:i.buttonBackgroundColor},...i.buttonTextColor&&{color:i.buttonTextColor},...i.buttonSize&&{width:i.buttonSize,height:i.buttonSize,fontSize:`calc(${i.buttonSize} * 0.5)`},...i.buttonBorderRadius&&{borderRadius:i.buttonBorderRadius},...i.boxShadow&&{boxShadow:i.boxShadow}},ma={...i.windowWidth&&!s&&!d&&{width:i.windowWidth},...i.windowHeight&&!s&&!d&&{height:i.windowHeight},...i.windowBorderRadius&&{borderRadius:i.windowBorderRadius},...i.fontFamily&&{fontFamily:i.fontFamily},...i.fontSize&&{fontSize:i.fontSize},...i.sidebarWidth&&s&&!u&&{width:i.sidebarWidth},...i.sidebarFoldedWidth&&s&&u&&{width:i.sidebarFoldedWidth},...d&&{width:da}};return(0,a.jsxs)(a.Fragment,{children:[!s&&!d&&(0,a.jsxs)("button",{className:`inapp-ai-button ${aa} ${ia}`,style:xa,onClick:()=>L(!I),"aria-label":I?"Close AI Assistant":"Open AI Assistant","aria-expanded":I,"aria-haspopup":"dialog",tabIndex:0,children:[I?"\u2715":i.buttonIcon||"\u{1F916}",!v&&(0,a.jsx)("span",{className:"inapp-ai-offline-indicator",role:"status","aria-label":"Backend disconnected"})]}),I&&(0,a.jsxs)("div",{ref:G,role:"dialog","aria-label":"AI Assistant Chat","aria-modal":!s&&!d?"true":void 0,className:`inapp-ai-window ${ba} ${s||d?"":aa} ${ia} ${ua}`,style:ma,children:[d&&(0,a.jsx)("div",{className:`inapp-ai-resize-handle ${B?"inapp-ai-resize-handle-right":"inapp-ai-resize-handle-left"}`,onMouseDown:()=>J(!0),title:"Drag to resize"}),(s||d)&&u?(0,a.jsxs)("div",{className:"inapp-ai-folded-content",onClick:_,style:{cursor:"pointer"},title:"Click to unfold",children:[(0,a.jsx)("div",{className:"inapp-ai-folded-icon",children:i.buttonIcon||"\u{1F916}"}),(0,a.jsx)("div",{className:"inapp-ai-folded-text",children:"AI"}),h.length>0&&(0,a.jsx)("div",{className:"inapp-ai-message-count",children:h.length})]}):(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)("div",{className:"inapp-ai-header",style:{...i.headerBackground&&{background:i.headerBackground},...i.headerTextColor&&{color:i.headerTextColor}},children:[(0,a.jsxs)("div",{className:"inapp-ai-header-title",children:[(0,a.jsx)("span",{className:"inapp-ai-header-icon",children:i.buttonIcon||"\u{1F916}"}),(0,a.jsxs)("div",{children:[(0,a.jsx)("h3",{children:i.headerTitle||"AI Assistant"}),(0,a.jsx)("p",{children:v?(0,a.jsxs)("span",{className:"inapp-ai-status-connected",children:[(0,a.jsx)("span",{className:"inapp-ai-status-dot"}),"Connected"]}):(0,a.jsxs)("span",{className:"inapp-ai-status-disconnected",children:[(0,a.jsx)("span",{className:"inapp-ai-status-dot"}),"Disconnected"]})})]})]}),(s||d)&&(0,a.jsx)("button",{className:"inapp-ai-header-fold-btn",onClick:_,"aria-label":u?`Unfold ${s?"sidebar":"panel"}`:`Fold ${s?"sidebar":"panel"}`,title:u?`Unfold ${s?"sidebar":"panel"}`:`Fold ${s?"sidebar":"panel"}`,children:ca||B?"\u25C0":"\u25B6"}),!s&&!d&&(0,a.jsx)("button",{className:"inapp-ai-close-btn",onClick:()=>L(!1),"aria-label":"Close",children:"\u2715"})]}),V&&(0,a.jsx)(Na,{error:V,onDismiss:()=>y(null)}),(0,a.jsxs)("div",{className:"inapp-ai-messages",role:"log","aria-live":"polite","aria-label":"Chat messages",children:[h.length===0?(0,a.jsxs)("div",{className:"inapp-ai-empty-state",role:"status",children:[(0,a.jsx)("div",{className:"inapp-ai-empty-icon","aria-hidden":"true",children:"\u{1F4AC}"}),(0,a.jsx)("h4",{children:"Start a conversation"}),(0,a.jsx)("p",{children:"Ask me anything! I'm powered by OpenAI."})]}):h.map(e=>(0,a.jsxs)("div",{className:`inapp-ai-message inapp-ai-message-${e.role}`,role:"article","aria-label":`${e.role==="user"?"User":"Assistant"} message`,children:[(0,a.jsx)("div",{className:"inapp-ai-message-icon","aria-hidden":"true",children:e.role==="user"?"\u{1F464}":"\u{1F916}"}),(0,a.jsxs)("div",{className:"inapp-ai-message-content",children:[(0,a.jsx)("div",{className:"inapp-ai-message-text",style:{...e.role==="user"&&i.userMessageBackground&&{background:i.userMessageBackground},...e.role==="user"&&i.userMessageColor&&{color:i.userMessageColor},...e.role==="assistant"&&i.assistantMessageBackground&&{background:i.assistantMessageBackground},...e.role==="assistant"&&i.assistantMessageColor&&{color:i.assistantMessageColor},...i.borderRadius&&{borderRadius:i.borderRadius}},children:e.role==="assistant"?(0,a.jsx)(na.default,{components:{code:Ta},children:e.content}):e.content}),(0,a.jsxs)("div",{className:"inapp-ai-message-time",children:[e.timestamp.toLocaleTimeString(),e.usage&&(0,a.jsxs)("span",{className:"inapp-ai-message-tokens",children:[" \u2022 ",e.usage.totalTokens," tokens"]})]})]})]},e.id)),f&&(0,a.jsxs)("div",{className:"inapp-ai-message inapp-ai-message-assistant",children:[(0,a.jsx)("div",{className:"inapp-ai-message-icon",children:(0,a.jsx)("div",{style:{animation:"pulse 2s infinite"},children:"\u{1F916}"})}),(0,a.jsx)("div",{className:"inapp-ai-message-content",children:(0,a.jsxs)("div",{style:{display:"flex",flexDirection:"column",gap:"8px"},children:[(0,a.jsxs)("div",{className:"inapp-ai-typing-indicator",children:[(0,a.jsx)("span",{}),(0,a.jsx)("span",{}),(0,a.jsx)("span",{})]}),(0,a.jsx)(za,{})]})})]}),(0,a.jsx)("div",{ref:q})]}),(0,a.jsxs)("div",{className:"inapp-ai-input-area",role:"form","aria-label":"Message input",children:[h.length>0&&(0,a.jsxs)("button",{className:"inapp-ai-clear-btn",onClick:fa,disabled:f,"aria-label":"Clear conversation history",tabIndex:0,children:[(0,a.jsx)("span",{"aria-hidden":"true",children:"\u{1F5D1}\uFE0F"})," Clear"]}),(0,a.jsxs)("div",{className:"inapp-ai-input-wrapper",children:[(0,a.jsx)("input",{ref:Q,type:"text",className:"inapp-ai-input",placeholder:i.inputPlaceholder||"Type your message...",value:F,onChange:e=>j(e.target.value),onKeyPress:ga,disabled:f||!v,"aria-label":"Message input","aria-describedby":"send-hint",tabIndex:0,style:{...i.inputBackground&&{background:i.inputBackground},...i.inputBorderColor&&{borderColor:i.inputBorderColor},...i.inputTextColor&&{color:i.inputTextColor}}}),(0,a.jsxs)("button",{className:"inapp-ai-send-btn",onClick:Z,disabled:f||!v||!F.trim(),"aria-label":"Send message",tabIndex:0,children:[(0,a.jsx)("span",{"aria-hidden":"true",children:f?"\u23F3":"\u2B06"}),(0,a.jsx)("span",{className:"sr-only",children:f?"Sending...":"Send message"})]}),(0,a.jsx)("span",{id:"send-hint",className:"sr-only",children:"Press Enter to send"})]})]})]})]})]})}0&&(module.exports={InAppAI});
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/components/InAppAI.tsx"],"sourcesContent":["export { InAppAI } from './components/InAppAI';\nexport type {\n CustomStyles,\n Tool,\n InAppAIProps,\n} from './types';\n","import { useState, useEffect, useRef } from 'react';\nimport ReactMarkdown from 'react-markdown';\nimport { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';\nimport { vscDarkPlus } from 'react-syntax-highlighter/dist/esm/styles/prism';\nimport type { CustomStyles, Tool, InAppAIProps } from '../types';\nimport './themes.css';\nimport './InAppAI.css';\n\ninterface Message {\n id: string;\n role: 'user' | 'assistant';\n content: string;\n timestamp: Date;\n usage?: {\n promptTokens: number;\n completionTokens: number;\n totalTokens: number;\n };\n}\n\n// Loading skeleton component\nfunction LoadingSkeleton() {\n return (\n <div\n style={{\n display: 'flex',\n flexDirection: 'column',\n gap: '8px',\n padding: '12px 16px',\n background: 'var(--inapp-ai-assistant-bg)',\n borderRadius: 'var(--inapp-ai-border-radius)',\n }}\n >\n <div\n style={{\n height: '14px',\n background: 'linear-gradient(90deg, #e0e0e0 25%, #f0f0f0 50%, #e0e0e0 75%)',\n backgroundSize: '200% 100%',\n animation: 'shimmer 1.5s infinite',\n borderRadius: '4px',\n }}\n />\n <div\n style={{\n height: '14px',\n width: '90%',\n background: 'linear-gradient(90deg, #e0e0e0 25%, #f0f0f0 50%, #e0e0e0 75%)',\n backgroundSize: '200% 100%',\n animation: 'shimmer 1.5s infinite',\n animationDelay: '0.1s',\n borderRadius: '4px',\n }}\n />\n <div\n style={{\n height: '14px',\n width: '75%',\n background: 'linear-gradient(90deg, #e0e0e0 25%, #f0f0f0 50%, #e0e0e0 75%)',\n backgroundSize: '200% 100%',\n animation: 'shimmer 1.5s infinite',\n animationDelay: '0.2s',\n borderRadius: '4px',\n }}\n />\n <style>{`\n @keyframes shimmer {\n 0% { background-position: 200% 0; }\n 100% { background-position: -200% 0; }\n }\n `}</style>\n </div>\n );\n}\n\n// Error message component with enhanced display\ninterface ErrorMessageProps {\n error: string;\n onDismiss: () => void;\n}\n\nfunction ErrorMessage({ error, onDismiss }: ErrorMessageProps) {\n // Determine error type based on message\n const getErrorType = (msg: string) => {\n if (msg.includes('not responding') || msg.includes('connection') || msg.includes('network')) {\n return { type: 'connection', icon: '🔌', title: 'Connection Error' };\n }\n if (msg.includes('timeout')) {\n return { type: 'timeout', icon: '⏱️', title: 'Request Timeout' };\n }\n if (msg.includes('rate limit')) {\n return { type: 'rateLimit', icon: '🚦', title: 'Rate Limit' };\n }\n if (msg.includes('authentication') || msg.includes('unauthorized')) {\n return { type: 'auth', icon: '🔒', title: 'Authentication Error' };\n }\n return { type: 'generic', icon: '⚠️', title: 'Error' };\n };\n\n const errorInfo = getErrorType(error);\n\n return (\n <div\n className=\"inapp-ai-error-banner\"\n role=\"alert\"\n aria-live=\"assertive\"\n style={{\n display: 'flex',\n alignItems: 'flex-start',\n gap: '12px',\n padding: '14px 16px',\n background: 'linear-gradient(135deg, #fff3cd 0%, #ffe9a6 100%)',\n borderLeft: '4px solid #ff9800',\n borderRadius: '0',\n }}\n >\n <span style={{ fontSize: '20px' }}>{errorInfo.icon}</span>\n <div style={{ flex: 1, minWidth: 0 }}>\n <div style={{ fontWeight: 600, marginBottom: '4px', color: '#856404' }}>\n {errorInfo.title}\n </div>\n <div style={{ fontSize: '13px', color: '#856404', wordBreak: 'break-word' }}>\n {error}\n </div>\n {errorInfo.type === 'connection' && (\n <div style={{ fontSize: '12px', marginTop: '6px', color: '#997404' }}>\n 💡 Make sure the backend server is running on the correct port\n </div>\n )}\n </div>\n <button\n onClick={onDismiss}\n style={{\n background: 'none',\n border: 'none',\n color: '#856404',\n cursor: 'pointer',\n padding: '4px 8px',\n fontSize: '16px',\n lineHeight: 1,\n }}\n aria-label=\"Dismiss error\"\n >\n ✕\n </button>\n </div>\n );\n}\n\n// Code block component with syntax highlighting and copy button\ninterface CodeBlockProps {\n inline?: boolean;\n className?: string;\n children?: React.ReactNode;\n}\n\nfunction CodeBlock({ inline, className, children, ...props }: CodeBlockProps) {\n const [copied, setCopied] = useState(false);\n\n // Extract language from className (format: language-js, language-python, etc.)\n const match = /language-(\\w+)/.exec(className || '');\n const language = match ? match[1] : '';\n\n const codeString = String(children).replace(/\\n$/, '');\n\n const handleCopy = () => {\n navigator.clipboard.writeText(codeString);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n };\n\n // Inline code (backticks)\n if (inline) {\n return <code className={className} {...props}>{children}</code>;\n }\n\n // Code block with syntax highlighting\n return (\n <div style={{ position: 'relative', marginTop: '8px', marginBottom: '8px' }}>\n <button\n onClick={handleCopy}\n style={{\n position: 'absolute',\n top: '8px',\n right: '8px',\n padding: '4px 8px',\n background: copied ? '#28a745' : 'rgba(255, 255, 255, 0.1)',\n color: 'white',\n border: 'none',\n borderRadius: '4px',\n cursor: 'pointer',\n fontSize: '12px',\n zIndex: 1,\n transition: 'background 0.2s',\n }}\n aria-label=\"Copy code\"\n >\n {copied ? '✓ Copied!' : '📋 Copy'}\n </button>\n <SyntaxHighlighter\n language={language || 'text'}\n style={vscDarkPlus}\n customStyle={{\n borderRadius: '8px',\n padding: '16px',\n fontSize: '13px',\n marginTop: 0,\n marginBottom: 0,\n }}\n {...props}\n >\n {codeString}\n </SyntaxHighlighter>\n </div>\n );\n}\n\nexport function InAppAI({\n endpoint = 'http://localhost:3001',\n position = 'bottom-right',\n displayMode = 'popup',\n defaultFolded = false,\n theme = 'light',\n context,\n customStyles = {},\n tools = [],\n panelMinWidth = '20%',\n panelMaxWidth = '33.33%',\n panelDefaultWidth = '25%',\n onPanelResize\n}: InAppAIProps) {\n const [isOpen, setIsOpen] = useState(displayMode.startsWith('sidebar') || displayMode.startsWith('panel'));\n const [isFolded, setIsFolded] = useState(defaultFolded && (displayMode.startsWith('sidebar') || displayMode.startsWith('panel')));\n const [messages, setMessages] = useState<Message[]>([]);\n const [inputValue, setInputValue] = useState('');\n const [isLoading, setIsLoading] = useState(false);\n const [isConnected, setIsConnected] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [panelWidth, setPanelWidth] = useState(panelDefaultWidth);\n const [isResizing, setIsResizing] = useState(false);\n const messagesEndRef = useRef<HTMLDivElement>(null);\n const conversationId = useRef(`react-demo-${Date.now()}`);\n const resizeRef = useRef<HTMLDivElement>(null);\n const inputRef = useRef<HTMLInputElement>(null);\n\n const isSidebar = displayMode.startsWith('sidebar');\n const isPanel = displayMode.startsWith('panel');\n const isLeftSidebar = displayMode === 'sidebar-left';\n // const isRightSidebar = displayMode === 'sidebar-right';\n const isLeftPanel = displayMode === 'panel-left';\n // const isRightPanel = displayMode === 'panel-right';\n\n // For sidebar and panel mode, start open\n useEffect(() => {\n if (isSidebar || isPanel) {\n setIsOpen(true);\n }\n }, [isSidebar, isPanel]);\n\n // Panel resize handlers\n useEffect(() => {\n if (!isPanel || !isResizing) return;\n\n const handleMouseMove = (e: MouseEvent) => {\n const container = resizeRef.current?.parentElement;\n if (!container) return;\n\n const containerRect = container.getBoundingClientRect();\n let newWidth: number;\n\n if (isLeftPanel) {\n newWidth = e.clientX;\n } else {\n newWidth = containerRect.width - e.clientX;\n }\n\n // Convert to percentage\n const widthPercent = (newWidth / containerRect.width) * 100;\n\n // Parse min/max widths\n const minPercent = parseFloat(panelMinWidth);\n const maxPercent = parseFloat(panelMaxWidth);\n\n // Clamp width between min and max\n const clampedPercent = Math.max(minPercent, Math.min(maxPercent, widthPercent));\n const newWidthStr = `${clampedPercent}%`;\n\n setPanelWidth(newWidthStr);\n if (onPanelResize) {\n onPanelResize(newWidth);\n }\n };\n\n const handleMouseUp = () => {\n setIsResizing(false);\n };\n\n document.addEventListener('mousemove', handleMouseMove);\n document.addEventListener('mouseup', handleMouseUp);\n\n return () => {\n document.removeEventListener('mousemove', handleMouseMove);\n document.removeEventListener('mouseup', handleMouseUp);\n };\n }, [isResizing, isPanel, isLeftPanel, panelMinWidth, panelMaxWidth, onPanelResize]);\n\n // Check backend connection\n useEffect(() => {\n const checkConnection = async () => {\n try {\n const response = await fetch(`${endpoint}/health`);\n if (response.ok) {\n setIsConnected(true);\n setError(null);\n } else {\n setError('Backend not responding');\n }\n } catch (err) {\n setError('Failed to connect to backend');\n setIsConnected(false);\n }\n };\n\n checkConnection();\n const interval = setInterval(checkConnection, 30000); // Check every 30s\n return () => clearInterval(interval);\n }, [endpoint]);\n\n // Auto-scroll to bottom\n useEffect(() => {\n messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });\n }, [messages]);\n\n // Refocus input after loading completes\n useEffect(() => {\n if (!isLoading && isConnected) {\n // Small delay to ensure DOM has updated\n setTimeout(() => {\n inputRef.current?.focus();\n }, 100);\n }\n }, [isLoading, isConnected]);\n\n const sendMessage = async () => {\n const message = inputValue.trim();\n if (!message || isLoading) return;\n\n // Add user message\n const userMessage: Message = {\n id: `${Date.now()}-user`,\n role: 'user',\n content: message,\n timestamp: new Date(),\n };\n\n setMessages(prev => [...prev, userMessage]);\n setInputValue('');\n setIsLoading(true);\n setError(null);\n\n try {\n // Helper to get fresh context (supports both static and function contexts)\n const getContext = () => typeof context === 'function' ? context() : context;\n\n // Prepare tool definitions (without handlers) for backend in OpenAI format\n const toolDefinitions = tools.map(({ name, description, parameters }) => ({\n type: 'function' as const,\n function: {\n name,\n description,\n parameters,\n },\n }));\n\n const response = await fetch(`${endpoint}/chat`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n message,\n conversationId: conversationId.current,\n context: getContext(),\n tools: toolDefinitions.length > 0 ? toolDefinitions : undefined,\n disableCache: false,\n }),\n });\n\n if (!response.ok) {\n throw new Error('Failed to get response');\n }\n\n const data = await response.json();\n\n // Check if AI returned tool calls\n if (data.toolCalls && data.toolCalls.length > 0) {\n // Execute tool handlers locally\n const results = await Promise.all(\n data.toolCalls.map(async (toolCall: any) => {\n // OpenAI format: {id, type, function: {name, arguments}}\n const toolName = toolCall.function?.name || toolCall.name;\n const toolArgs = toolCall.function?.arguments\n ? JSON.parse(toolCall.function.arguments)\n : toolCall.parameters;\n\n const tool = tools.find(t => t.name === toolName);\n if (!tool) {\n return { success: false, error: `Tool '${toolName}' not found` };\n }\n try {\n const result = await Promise.resolve(tool.handler(toolArgs));\n return result;\n } catch (error: any) {\n console.error(`Tool '${tool.name}' failed:`, error);\n return { success: false, error: error.message };\n }\n })\n );\n\n // Send tool results back to AI for natural language response\n const toolResultsMessage = results\n .map((r: any, idx: any) => {\n const toolCall = data.toolCalls[idx];\n const toolName = toolCall.function?.name || toolCall.name;\n return `Tool \"${toolName}\" result: ${JSON.stringify(r)}`;\n })\n .join('\\n');\n\n // IMPORTANT: Get fresh context after tool execution\n // Tool handlers may have updated state (e.g., added/completed todos)\n // By calling getContext() again, we ensure the AI sees the updated state\n const followUpResponse = await fetch(`${endpoint}/chat`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n message: toolResultsMessage,\n conversationId: conversationId.current,\n context: getContext(), // Fresh context after tool execution\n disableCache: false,\n }),\n });\n\n if (!followUpResponse.ok) {\n throw new Error('Failed to get AI response for tool results');\n }\n\n const followUpData = await followUpResponse.json();\n\n const assistantMessage: Message = {\n id: `${Date.now()}-assistant`,\n role: 'assistant',\n content: followUpData.message || 'I executed the tools successfully.',\n timestamp: new Date(),\n usage: followUpData.usage,\n };\n\n setMessages(prev => [...prev, assistantMessage]);\n } else {\n const assistantMessage: Message = {\n id: `${Date.now()}-assistant`,\n role: 'assistant',\n content: data.message,\n timestamp: new Date(),\n usage: data.usage,\n };\n\n setMessages(prev => [...prev, assistantMessage]);\n }\n } catch (err) {\n console.error('❌ Error:', err);\n setError(err instanceof Error ? err.message : 'Unknown error');\n } finally {\n setIsLoading(false);\n }\n };\n\n const handleKeyPress = (e: React.KeyboardEvent) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault();\n sendMessage();\n }\n };\n\n const clearMessages = () => {\n setMessages([]);\n conversationId.current = `react-demo-${Date.now()}`;\n };\n\n const toggleFolded = () => {\n setIsFolded(!isFolded);\n };\n\n const positionClass = `inapp-ai-${position}`;\n // Don't add a theme class for 'light' since it's the default\n const themeClass = theme && theme !== 'light' ? `inapp-ai-theme-${theme}` : '';\n const modeClass = isSidebar\n ? `inapp-ai-sidebar inapp-ai-${displayMode}`\n : isPanel\n ? `inapp-ai-panel inapp-ai-${displayMode}`\n : 'inapp-ai-popup';\n const foldedClass = isFolded ? 'inapp-ai-folded' : '';\n\n // Build custom button style\n const buttonStyle: React.CSSProperties = {\n ...(customStyles.buttonBackgroundColor && { background: customStyles.buttonBackgroundColor }),\n ...(customStyles.buttonTextColor && { color: customStyles.buttonTextColor }),\n ...(customStyles.buttonSize && {\n width: customStyles.buttonSize,\n height: customStyles.buttonSize,\n fontSize: `calc(${customStyles.buttonSize} * 0.5)`\n }),\n ...(customStyles.buttonBorderRadius && { borderRadius: customStyles.buttonBorderRadius }),\n ...(customStyles.boxShadow && { boxShadow: customStyles.boxShadow }),\n };\n\n // Build custom window style\n const windowStyle: React.CSSProperties = {\n ...(customStyles.windowWidth && !isSidebar && !isPanel && { width: customStyles.windowWidth }),\n ...(customStyles.windowHeight && !isSidebar && !isPanel && { height: customStyles.windowHeight }),\n ...(customStyles.windowBorderRadius && { borderRadius: customStyles.windowBorderRadius }),\n ...(customStyles.fontFamily && { fontFamily: customStyles.fontFamily }),\n ...(customStyles.fontSize && { fontSize: customStyles.fontSize }),\n ...(customStyles.sidebarWidth && isSidebar && !isFolded && { width: customStyles.sidebarWidth }),\n ...(customStyles.sidebarFoldedWidth && isSidebar && isFolded && { width: customStyles.sidebarFoldedWidth }),\n ...(isPanel && { width: panelWidth }),\n };\n\n return (\n <>\n {/* Chat Button (only for popup mode) */}\n {!isSidebar && !isPanel && (\n <button\n className={`inapp-ai-button ${positionClass} ${themeClass}`}\n style={buttonStyle}\n onClick={() => setIsOpen(!isOpen)}\n aria-label={isOpen ? \"Close AI Assistant\" : \"Open AI Assistant\"}\n aria-expanded={isOpen}\n aria-haspopup=\"dialog\"\n tabIndex={0}\n >\n {isOpen ? '✕' : (customStyles.buttonIcon || '🤖')}\n {!isConnected && (\n <span\n className=\"inapp-ai-offline-indicator\"\n role=\"status\"\n aria-label=\"Backend disconnected\"\n />\n )}\n </button>\n )}\n\n {/* Chat Window */}\n {isOpen && (\n <div\n ref={resizeRef}\n role=\"dialog\"\n aria-label=\"AI Assistant Chat\"\n aria-modal={!isSidebar && !isPanel ? \"true\" : undefined}\n className={`inapp-ai-window ${modeClass} ${isSidebar || isPanel ? '' : positionClass} ${themeClass} ${foldedClass}`}\n style={windowStyle}\n >\n {/* Resize Handle for Panel */}\n {isPanel && (\n <div\n className={`inapp-ai-resize-handle ${isLeftPanel ? 'inapp-ai-resize-handle-right' : 'inapp-ai-resize-handle-left'}`}\n onMouseDown={() => setIsResizing(true)}\n title=\"Drag to resize\"\n />\n )}\n\n {/* Folded State Content */}\n {(isSidebar || isPanel) && isFolded ? (\n <div\n className=\"inapp-ai-folded-content\"\n onClick={toggleFolded}\n style={{ cursor: 'pointer' }}\n title=\"Click to unfold\"\n >\n <div className=\"inapp-ai-folded-icon\">\n {customStyles.buttonIcon || '🤖'}\n </div>\n <div className=\"inapp-ai-folded-text\">\n AI\n </div>\n {messages.length > 0 && (\n <div className=\"inapp-ai-message-count\">\n {messages.length}\n </div>\n )}\n </div>\n ) : (\n <>\n {/* Header */}\n <div className=\"inapp-ai-header\" style={{\n ...(customStyles.headerBackground && { background: customStyles.headerBackground }),\n ...(customStyles.headerTextColor && { color: customStyles.headerTextColor }),\n }}>\n <div className=\"inapp-ai-header-title\">\n <span className=\"inapp-ai-header-icon\">{customStyles.buttonIcon || '🤖'}</span>\n <div>\n <h3>{customStyles.headerTitle || 'AI Assistant'}</h3>\n <p>\n {isConnected ? (\n <span className=\"inapp-ai-status-connected\">\n <span className=\"inapp-ai-status-dot\" />\n Connected\n </span>\n ) : (\n <span className=\"inapp-ai-status-disconnected\">\n <span className=\"inapp-ai-status-dot\" />\n Disconnected\n </span>\n )}\n </p>\n </div>\n </div>\n {/* Fold button for panels (in header top right) */}\n {(isSidebar || isPanel) && (\n <button\n className=\"inapp-ai-header-fold-btn\"\n onClick={toggleFolded}\n aria-label={isFolded ? `Unfold ${isSidebar ? 'sidebar' : 'panel'}` : `Fold ${isSidebar ? 'sidebar' : 'panel'}`}\n title={isFolded ? `Unfold ${isSidebar ? 'sidebar' : 'panel'}` : `Fold ${isSidebar ? 'sidebar' : 'panel'}`}\n >\n {(isLeftSidebar || isLeftPanel) ? '◀' : '▶'}\n </button>\n )}\n {/* Close button for popup mode */}\n {!isSidebar && !isPanel && (\n <button\n className=\"inapp-ai-close-btn\"\n onClick={() => setIsOpen(false)}\n aria-label=\"Close\"\n >\n ✕\n </button>\n )}\n </div>\n\n {/* Error Banner */}\n {error && (\n <ErrorMessage error={error} onDismiss={() => setError(null)} />\n )}\n\n {/* Messages */}\n <div\n className=\"inapp-ai-messages\"\n role=\"log\"\n aria-live=\"polite\"\n aria-label=\"Chat messages\"\n >\n {messages.length === 0 ? (\n <div className=\"inapp-ai-empty-state\" role=\"status\">\n <div className=\"inapp-ai-empty-icon\" aria-hidden=\"true\">💬</div>\n <h4>Start a conversation</h4>\n <p>Ask me anything! I'm powered by OpenAI.</p>\n </div>\n ) : (\n messages.map((msg) => (\n <div\n key={msg.id}\n className={`inapp-ai-message inapp-ai-message-${msg.role}`}\n role=\"article\"\n aria-label={`${msg.role === 'user' ? 'User' : 'Assistant'} message`}\n >\n <div className=\"inapp-ai-message-icon\" aria-hidden=\"true\">\n {msg.role === 'user' ? '👤' : '🤖'}\n </div>\n <div className=\"inapp-ai-message-content\">\n <div className=\"inapp-ai-message-text\" style={{\n ...(msg.role === 'user' && customStyles.userMessageBackground && { background: customStyles.userMessageBackground }),\n ...(msg.role === 'user' && customStyles.userMessageColor && { color: customStyles.userMessageColor }),\n ...(msg.role === 'assistant' && customStyles.assistantMessageBackground && { background: customStyles.assistantMessageBackground }),\n ...(msg.role === 'assistant' && customStyles.assistantMessageColor && { color: customStyles.assistantMessageColor }),\n ...(customStyles.borderRadius && { borderRadius: customStyles.borderRadius }),\n }}>\n {msg.role === 'assistant' ? (\n <ReactMarkdown\n components={{\n code: CodeBlock as any,\n }}\n >\n {msg.content}\n </ReactMarkdown>\n ) : (\n msg.content\n )}\n </div>\n <div className=\"inapp-ai-message-time\">\n {msg.timestamp.toLocaleTimeString()}\n {msg.usage && (\n <span className=\"inapp-ai-message-tokens\">\n {' • '}{msg.usage.totalTokens} tokens\n </span>\n )}\n </div>\n </div>\n </div>\n ))\n )}\n {isLoading && (\n <div className=\"inapp-ai-message inapp-ai-message-assistant\">\n <div className=\"inapp-ai-message-icon\">\n <div style={{ animation: 'pulse 2s infinite' }}>🤖</div>\n </div>\n <div className=\"inapp-ai-message-content\">\n <div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>\n <div className=\"inapp-ai-typing-indicator\">\n <span></span>\n <span></span>\n <span></span>\n </div>\n <LoadingSkeleton />\n </div>\n </div>\n </div>\n )}\n <div ref={messagesEndRef} />\n </div>\n\n {/* Input Area */}\n <div className=\"inapp-ai-input-area\" role=\"form\" aria-label=\"Message input\">\n {messages.length > 0 && (\n <button\n className=\"inapp-ai-clear-btn\"\n onClick={clearMessages}\n disabled={isLoading}\n aria-label=\"Clear conversation history\"\n tabIndex={0}\n >\n <span aria-hidden=\"true\">🗑️</span> Clear\n </button>\n )}\n <div className=\"inapp-ai-input-wrapper\">\n <input\n ref={inputRef}\n type=\"text\"\n className=\"inapp-ai-input\"\n placeholder={customStyles.inputPlaceholder || \"Type your message...\"}\n value={inputValue}\n onChange={(e) => setInputValue(e.target.value)}\n onKeyPress={handleKeyPress}\n disabled={isLoading || !isConnected}\n aria-label=\"Message input\"\n aria-describedby=\"send-hint\"\n tabIndex={0}\n style={{\n ...(customStyles.inputBackground && { background: customStyles.inputBackground }),\n ...(customStyles.inputBorderColor && { borderColor: customStyles.inputBorderColor }),\n ...(customStyles.inputTextColor && { color: customStyles.inputTextColor }),\n }}\n />\n <button\n className=\"inapp-ai-send-btn\"\n onClick={sendMessage}\n disabled={isLoading || !isConnected || !inputValue.trim()}\n aria-label=\"Send message\"\n tabIndex={0}\n >\n <span aria-hidden=\"true\">{isLoading ? '⏳' : '⬆'}</span>\n <span className=\"sr-only\">\n {isLoading ? 'Sending...' : 'Send message'}\n </span>\n </button>\n <span id=\"send-hint\" className=\"sr-only\">\n Press Enter to send\n </span>\n </div>\n </div>\n </>\n )}\n </div>\n )}\n </>\n );\n}\n"],"mappings":"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","names":["index_exports","__export","InAppAI","__toCommonJS","import_react","import_react_markdown","import_react_syntax_highlighter","import_prism","import_jsx_runtime","LoadingSkeleton","ErrorMessage","error","onDismiss","errorInfo","msg","CodeBlock","inline","className","children","props","copied","setCopied","match","language","codeString","handleCopy","SyntaxHighlighter","InAppAI","endpoint","position","displayMode","defaultFolded","theme","context","customStyles","tools","panelMinWidth","panelMaxWidth","panelDefaultWidth","onPanelResize","isOpen","setIsOpen","isFolded","setIsFolded","messages","setMessages","inputValue","setInputValue","isLoading","setIsLoading","isConnected","setIsConnected","setError","panelWidth","setPanelWidth","isResizing","setIsResizing","messagesEndRef","conversationId","resizeRef","inputRef","isSidebar","isPanel","isLeftSidebar","isLeftPanel","handleMouseMove","e","container","containerRect","newWidth","widthPercent","minPercent","maxPercent","newWidthStr","handleMouseUp","checkConnection","interval","sendMessage","message","userMessage","prev","getContext","toolDefinitions","name","description","parameters","response","data","toolResultsMessage","toolCall","toolName","toolArgs","tool","t","r","idx","followUpResponse","followUpData","assistantMessage","err","handleKeyPress","clearMessages","toggleFolded","positionClass","themeClass","modeClass","foldedClass","buttonStyle","windowStyle","ReactMarkdown"]}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import{useState as l,useEffect as A,useRef as L}from"react";import xa from"react-markdown";import{Prism as ma}from"react-syntax-highlighter";import{vscDarkPlus as ha}from"react-syntax-highlighter/dist/esm/styles/prism";import{Fragment as ra,jsx as i,jsxs as n}from"react/jsx-runtime";function va(){return n("div",{style:{display:"flex",flexDirection:"column",gap:"8px",padding:"12px 16px",background:"var(--inapp-ai-assistant-bg)",borderRadius:"var(--inapp-ai-border-radius)"},children:[i("div",{style:{height:"14px",background:"linear-gradient(90deg, #e0e0e0 25%, #f0f0f0 50%, #e0e0e0 75%)",backgroundSize:"200% 100%",animation:"shimmer 1.5s infinite",borderRadius:"4px"}}),i("div",{style:{height:"14px",width:"90%",background:"linear-gradient(90deg, #e0e0e0 25%, #f0f0f0 50%, #e0e0e0 75%)",backgroundSize:"200% 100%",animation:"shimmer 1.5s infinite",animationDelay:"0.1s",borderRadius:"4px"}}),i("div",{style:{height:"14px",width:"75%",background:"linear-gradient(90deg, #e0e0e0 25%, #f0f0f0 50%, #e0e0e0 75%)",backgroundSize:"200% 100%",animation:"shimmer 1.5s infinite",animationDelay:"0.2s",borderRadius:"4px"}}),i("style",{children:`
|
|
2
|
+
@keyframes shimmer {
|
|
3
|
+
0% { background-position: 200% 0; }
|
|
4
|
+
100% { background-position: -200% 0; }
|
|
5
|
+
}
|
|
6
|
+
`})]})}function ya({error:c,onDismiss:m}){let b=(o=>o.includes("not responding")||o.includes("connection")||o.includes("network")?{type:"connection",icon:"\u{1F50C}",title:"Connection Error"}:o.includes("timeout")?{type:"timeout",icon:"\u23F1\uFE0F",title:"Request Timeout"}:o.includes("rate limit")?{type:"rateLimit",icon:"\u{1F6A6}",title:"Rate Limit"}:o.includes("authentication")||o.includes("unauthorized")?{type:"auth",icon:"\u{1F512}",title:"Authentication Error"}:{type:"generic",icon:"\u26A0\uFE0F",title:"Error"})(c);return n("div",{className:"inapp-ai-error-banner",role:"alert","aria-live":"assertive",style:{display:"flex",alignItems:"flex-start",gap:"12px",padding:"14px 16px",background:"linear-gradient(135deg, #fff3cd 0%, #ffe9a6 100%)",borderLeft:"4px solid #ff9800",borderRadius:"0"},children:[i("span",{style:{fontSize:"20px"},children:b.icon}),n("div",{style:{flex:1,minWidth:0},children:[i("div",{style:{fontWeight:600,marginBottom:"4px",color:"#856404"},children:b.title}),i("div",{style:{fontSize:"13px",color:"#856404",wordBreak:"break-word"},children:c}),b.type==="connection"&&i("div",{style:{fontSize:"12px",marginTop:"6px",color:"#997404"},children:"\u{1F4A1} Make sure the backend server is running on the correct port"})]}),i("button",{onClick:m,style:{background:"none",border:"none",color:"#856404",cursor:"pointer",padding:"4px 8px",fontSize:"16px",lineHeight:1},"aria-label":"Dismiss error",children:"\u2715"})]})}function ka({inline:c,className:m,children:p,...b}){let[o,h]=l(!1),a=/language-(\w+)/.exec(m||""),R=a?a[1]:"",I=String(p).replace(/\n$/,""),B=()=>{navigator.clipboard.writeText(I),h(!0),setTimeout(()=>h(!1),2e3)};return c?i("code",{className:m,...b,children:p}):n("div",{style:{position:"relative",marginTop:"8px",marginBottom:"8px"},children:[i("button",{onClick:B,style:{position:"absolute",top:"8px",right:"8px",padding:"4px 8px",background:o?"#28a745":"rgba(255, 255, 255, 0.1)",color:"white",border:"none",borderRadius:"4px",cursor:"pointer",fontSize:"12px",zIndex:1,transition:"background 0.2s"},"aria-label":"Copy code",children:o?"\u2713 Copied!":"\u{1F4CB} Copy"}),i(ma,{language:R||"text",style:ha,customStyle:{borderRadius:"8px",padding:"16px",fontSize:"13px",marginTop:0,marginBottom:0},...b,children:I})]})}function wa({endpoint:c="http://localhost:3001",position:m="bottom-right",displayMode:p="popup",defaultFolded:b=!1,theme:o="light",context:h,customStyles:a={},tools:R=[],panelMinWidth:I="20%",panelMaxWidth:B="33.33%",panelDefaultWidth:ta="25%",onPanelResize:F}){let[z,W]=l(p.startsWith("sidebar")||p.startsWith("panel")),[u,pa]=l(b&&(p.startsWith("sidebar")||p.startsWith("panel"))),[v,P]=l([]),[H,K]=l(""),[g,V]=l(!1),[y,X]=l(!1),[J,k]=l(null),[oa,sa]=l(ta),[q,G]=l(!1),Q=L(null),U=L(`react-demo-${Date.now()}`),Z=L(null),_=L(null),r=p.startsWith("sidebar"),t=p.startsWith("panel"),da=p==="sidebar-left",D=p==="panel-left";A(()=>{(r||t)&&W(!0)},[r,t]),A(()=>{if(!t||!q)return;let e=s=>{let N=Z.current?.parentElement;if(!N)return;let T=N.getBoundingClientRect(),d;D?d=s.clientX:d=T.width-s.clientX;let C=d/T.width*100,x=parseFloat(I),E=parseFloat(B),Y=`${Math.max(x,Math.min(E,C))}%`;sa(Y),F&&F(d)},w=()=>{G(!1)};return document.addEventListener("mousemove",e),document.addEventListener("mouseup",w),()=>{document.removeEventListener("mousemove",e),document.removeEventListener("mouseup",w)}},[q,t,D,I,B,F]),A(()=>{let e=async()=>{try{(await fetch(`${c}/health`)).ok?(X(!0),k(null)):k("Backend not responding")}catch{k("Failed to connect to backend"),X(!1)}};e();let w=setInterval(e,3e4);return()=>clearInterval(w)},[c]),A(()=>{Q.current?.scrollIntoView({behavior:"smooth"})},[v]),A(()=>{!g&&y&&setTimeout(()=>{_.current?.focus()},100)},[g,y]);let aa=async()=>{let e=H.trim();if(!e||g)return;let w={id:`${Date.now()}-user`,role:"user",content:e,timestamp:new Date};P(s=>[...s,w]),K(""),V(!0),k(null);try{let s=()=>typeof h=="function"?h():h,N=R.map(({name:C,description:x,parameters:E})=>({type:"function",function:{name:C,description:x,parameters:E}})),T=await fetch(`${c}/chat`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({message:e,conversationId:U.current,context:s(),tools:N.length>0?N:void 0,disableCache:!1})});if(!T.ok)throw new Error("Failed to get response");let d=await T.json();if(d.toolCalls&&d.toolCalls.length>0){let x=(await Promise.all(d.toolCalls.map(async f=>{let S=f.function?.name||f.name,$=f.function?.arguments?JSON.parse(f.function.arguments):f.parameters,O=R.find(M=>M.name===S);if(!O)return{success:!1,error:`Tool '${S}' not found`};try{return await Promise.resolve(O.handler($))}catch(M){return console.error(`Tool '${O.name}' failed:`,M),{success:!1,error:M.message}}}))).map((f,S)=>{let $=d.toolCalls[S];return`Tool "${$.function?.name||$.name}" result: ${JSON.stringify(f)}`}).join(`
|
|
7
|
+
`),E=await fetch(`${c}/chat`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({message:x,conversationId:U.current,context:s(),disableCache:!1})});if(!E.ok)throw new Error("Failed to get AI response for tool results");let j=await E.json(),Y={id:`${Date.now()}-assistant`,role:"assistant",content:j.message||"I executed the tools successfully.",timestamp:new Date,usage:j.usage};P(f=>[...f,Y])}else{let C={id:`${Date.now()}-assistant`,role:"assistant",content:d.message,timestamp:new Date,usage:d.usage};P(x=>[...x,C])}}catch(s){console.error("\u274C Error:",s),k(s instanceof Error?s.message:"Unknown error")}finally{V(!1)}},la=e=>{e.key==="Enter"&&!e.shiftKey&&(e.preventDefault(),aa())},ca=()=>{P([]),U.current=`react-demo-${Date.now()}`},ia=()=>{pa(!u)},ea=`inapp-ai-${m}`,na=o&&o!=="light"?`inapp-ai-theme-${o}`:"",ga=r?`inapp-ai-sidebar inapp-ai-${p}`:t?`inapp-ai-panel inapp-ai-${p}`:"inapp-ai-popup",fa=u?"inapp-ai-folded":"",ba={...a.buttonBackgroundColor&&{background:a.buttonBackgroundColor},...a.buttonTextColor&&{color:a.buttonTextColor},...a.buttonSize&&{width:a.buttonSize,height:a.buttonSize,fontSize:`calc(${a.buttonSize} * 0.5)`},...a.buttonBorderRadius&&{borderRadius:a.buttonBorderRadius},...a.boxShadow&&{boxShadow:a.boxShadow}},ua={...a.windowWidth&&!r&&!t&&{width:a.windowWidth},...a.windowHeight&&!r&&!t&&{height:a.windowHeight},...a.windowBorderRadius&&{borderRadius:a.windowBorderRadius},...a.fontFamily&&{fontFamily:a.fontFamily},...a.fontSize&&{fontSize:a.fontSize},...a.sidebarWidth&&r&&!u&&{width:a.sidebarWidth},...a.sidebarFoldedWidth&&r&&u&&{width:a.sidebarFoldedWidth},...t&&{width:oa}};return n(ra,{children:[!r&&!t&&n("button",{className:`inapp-ai-button ${ea} ${na}`,style:ba,onClick:()=>W(!z),"aria-label":z?"Close AI Assistant":"Open AI Assistant","aria-expanded":z,"aria-haspopup":"dialog",tabIndex:0,children:[z?"\u2715":a.buttonIcon||"\u{1F916}",!y&&i("span",{className:"inapp-ai-offline-indicator",role:"status","aria-label":"Backend disconnected"})]}),z&&n("div",{ref:Z,role:"dialog","aria-label":"AI Assistant Chat","aria-modal":!r&&!t?"true":void 0,className:`inapp-ai-window ${ga} ${r||t?"":ea} ${na} ${fa}`,style:ua,children:[t&&i("div",{className:`inapp-ai-resize-handle ${D?"inapp-ai-resize-handle-right":"inapp-ai-resize-handle-left"}`,onMouseDown:()=>G(!0),title:"Drag to resize"}),(r||t)&&u?n("div",{className:"inapp-ai-folded-content",onClick:ia,style:{cursor:"pointer"},title:"Click to unfold",children:[i("div",{className:"inapp-ai-folded-icon",children:a.buttonIcon||"\u{1F916}"}),i("div",{className:"inapp-ai-folded-text",children:"AI"}),v.length>0&&i("div",{className:"inapp-ai-message-count",children:v.length})]}):n(ra,{children:[n("div",{className:"inapp-ai-header",style:{...a.headerBackground&&{background:a.headerBackground},...a.headerTextColor&&{color:a.headerTextColor}},children:[n("div",{className:"inapp-ai-header-title",children:[i("span",{className:"inapp-ai-header-icon",children:a.buttonIcon||"\u{1F916}"}),n("div",{children:[i("h3",{children:a.headerTitle||"AI Assistant"}),i("p",{children:y?n("span",{className:"inapp-ai-status-connected",children:[i("span",{className:"inapp-ai-status-dot"}),"Connected"]}):n("span",{className:"inapp-ai-status-disconnected",children:[i("span",{className:"inapp-ai-status-dot"}),"Disconnected"]})})]})]}),(r||t)&&i("button",{className:"inapp-ai-header-fold-btn",onClick:ia,"aria-label":u?`Unfold ${r?"sidebar":"panel"}`:`Fold ${r?"sidebar":"panel"}`,title:u?`Unfold ${r?"sidebar":"panel"}`:`Fold ${r?"sidebar":"panel"}`,children:da||D?"\u25C0":"\u25B6"}),!r&&!t&&i("button",{className:"inapp-ai-close-btn",onClick:()=>W(!1),"aria-label":"Close",children:"\u2715"})]}),J&&i(ya,{error:J,onDismiss:()=>k(null)}),n("div",{className:"inapp-ai-messages",role:"log","aria-live":"polite","aria-label":"Chat messages",children:[v.length===0?n("div",{className:"inapp-ai-empty-state",role:"status",children:[i("div",{className:"inapp-ai-empty-icon","aria-hidden":"true",children:"\u{1F4AC}"}),i("h4",{children:"Start a conversation"}),i("p",{children:"Ask me anything! I'm powered by OpenAI."})]}):v.map(e=>n("div",{className:`inapp-ai-message inapp-ai-message-${e.role}`,role:"article","aria-label":`${e.role==="user"?"User":"Assistant"} message`,children:[i("div",{className:"inapp-ai-message-icon","aria-hidden":"true",children:e.role==="user"?"\u{1F464}":"\u{1F916}"}),n("div",{className:"inapp-ai-message-content",children:[i("div",{className:"inapp-ai-message-text",style:{...e.role==="user"&&a.userMessageBackground&&{background:a.userMessageBackground},...e.role==="user"&&a.userMessageColor&&{color:a.userMessageColor},...e.role==="assistant"&&a.assistantMessageBackground&&{background:a.assistantMessageBackground},...e.role==="assistant"&&a.assistantMessageColor&&{color:a.assistantMessageColor},...a.borderRadius&&{borderRadius:a.borderRadius}},children:e.role==="assistant"?i(xa,{components:{code:ka},children:e.content}):e.content}),n("div",{className:"inapp-ai-message-time",children:[e.timestamp.toLocaleTimeString(),e.usage&&n("span",{className:"inapp-ai-message-tokens",children:[" \u2022 ",e.usage.totalTokens," tokens"]})]})]})]},e.id)),g&&n("div",{className:"inapp-ai-message inapp-ai-message-assistant",children:[i("div",{className:"inapp-ai-message-icon",children:i("div",{style:{animation:"pulse 2s infinite"},children:"\u{1F916}"})}),i("div",{className:"inapp-ai-message-content",children:n("div",{style:{display:"flex",flexDirection:"column",gap:"8px"},children:[n("div",{className:"inapp-ai-typing-indicator",children:[i("span",{}),i("span",{}),i("span",{})]}),i(va,{})]})})]}),i("div",{ref:Q})]}),n("div",{className:"inapp-ai-input-area",role:"form","aria-label":"Message input",children:[v.length>0&&n("button",{className:"inapp-ai-clear-btn",onClick:ca,disabled:g,"aria-label":"Clear conversation history",tabIndex:0,children:[i("span",{"aria-hidden":"true",children:"\u{1F5D1}\uFE0F"})," Clear"]}),n("div",{className:"inapp-ai-input-wrapper",children:[i("input",{ref:_,type:"text",className:"inapp-ai-input",placeholder:a.inputPlaceholder||"Type your message...",value:H,onChange:e=>K(e.target.value),onKeyPress:la,disabled:g||!y,"aria-label":"Message input","aria-describedby":"send-hint",tabIndex:0,style:{...a.inputBackground&&{background:a.inputBackground},...a.inputBorderColor&&{borderColor:a.inputBorderColor},...a.inputTextColor&&{color:a.inputTextColor}}}),n("button",{className:"inapp-ai-send-btn",onClick:aa,disabled:g||!y||!H.trim(),"aria-label":"Send message",tabIndex:0,children:[i("span",{"aria-hidden":"true",children:g?"\u23F3":"\u2B06"}),i("span",{className:"sr-only",children:g?"Sending...":"Send message"})]}),i("span",{id:"send-hint",className:"sr-only",children:"Press Enter to send"})]})]})]})]})]})}export{wa as InAppAI};
|
|
8
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/InAppAI.tsx"],"sourcesContent":["import { useState, useEffect, useRef } from 'react';\nimport ReactMarkdown from 'react-markdown';\nimport { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';\nimport { vscDarkPlus } from 'react-syntax-highlighter/dist/esm/styles/prism';\nimport type { CustomStyles, Tool, InAppAIProps } from '../types';\nimport './themes.css';\nimport './InAppAI.css';\n\ninterface Message {\n id: string;\n role: 'user' | 'assistant';\n content: string;\n timestamp: Date;\n usage?: {\n promptTokens: number;\n completionTokens: number;\n totalTokens: number;\n };\n}\n\n// Loading skeleton component\nfunction LoadingSkeleton() {\n return (\n <div\n style={{\n display: 'flex',\n flexDirection: 'column',\n gap: '8px',\n padding: '12px 16px',\n background: 'var(--inapp-ai-assistant-bg)',\n borderRadius: 'var(--inapp-ai-border-radius)',\n }}\n >\n <div\n style={{\n height: '14px',\n background: 'linear-gradient(90deg, #e0e0e0 25%, #f0f0f0 50%, #e0e0e0 75%)',\n backgroundSize: '200% 100%',\n animation: 'shimmer 1.5s infinite',\n borderRadius: '4px',\n }}\n />\n <div\n style={{\n height: '14px',\n width: '90%',\n background: 'linear-gradient(90deg, #e0e0e0 25%, #f0f0f0 50%, #e0e0e0 75%)',\n backgroundSize: '200% 100%',\n animation: 'shimmer 1.5s infinite',\n animationDelay: '0.1s',\n borderRadius: '4px',\n }}\n />\n <div\n style={{\n height: '14px',\n width: '75%',\n background: 'linear-gradient(90deg, #e0e0e0 25%, #f0f0f0 50%, #e0e0e0 75%)',\n backgroundSize: '200% 100%',\n animation: 'shimmer 1.5s infinite',\n animationDelay: '0.2s',\n borderRadius: '4px',\n }}\n />\n <style>{`\n @keyframes shimmer {\n 0% { background-position: 200% 0; }\n 100% { background-position: -200% 0; }\n }\n `}</style>\n </div>\n );\n}\n\n// Error message component with enhanced display\ninterface ErrorMessageProps {\n error: string;\n onDismiss: () => void;\n}\n\nfunction ErrorMessage({ error, onDismiss }: ErrorMessageProps) {\n // Determine error type based on message\n const getErrorType = (msg: string) => {\n if (msg.includes('not responding') || msg.includes('connection') || msg.includes('network')) {\n return { type: 'connection', icon: '🔌', title: 'Connection Error' };\n }\n if (msg.includes('timeout')) {\n return { type: 'timeout', icon: '⏱️', title: 'Request Timeout' };\n }\n if (msg.includes('rate limit')) {\n return { type: 'rateLimit', icon: '🚦', title: 'Rate Limit' };\n }\n if (msg.includes('authentication') || msg.includes('unauthorized')) {\n return { type: 'auth', icon: '🔒', title: 'Authentication Error' };\n }\n return { type: 'generic', icon: '⚠️', title: 'Error' };\n };\n\n const errorInfo = getErrorType(error);\n\n return (\n <div\n className=\"inapp-ai-error-banner\"\n role=\"alert\"\n aria-live=\"assertive\"\n style={{\n display: 'flex',\n alignItems: 'flex-start',\n gap: '12px',\n padding: '14px 16px',\n background: 'linear-gradient(135deg, #fff3cd 0%, #ffe9a6 100%)',\n borderLeft: '4px solid #ff9800',\n borderRadius: '0',\n }}\n >\n <span style={{ fontSize: '20px' }}>{errorInfo.icon}</span>\n <div style={{ flex: 1, minWidth: 0 }}>\n <div style={{ fontWeight: 600, marginBottom: '4px', color: '#856404' }}>\n {errorInfo.title}\n </div>\n <div style={{ fontSize: '13px', color: '#856404', wordBreak: 'break-word' }}>\n {error}\n </div>\n {errorInfo.type === 'connection' && (\n <div style={{ fontSize: '12px', marginTop: '6px', color: '#997404' }}>\n 💡 Make sure the backend server is running on the correct port\n </div>\n )}\n </div>\n <button\n onClick={onDismiss}\n style={{\n background: 'none',\n border: 'none',\n color: '#856404',\n cursor: 'pointer',\n padding: '4px 8px',\n fontSize: '16px',\n lineHeight: 1,\n }}\n aria-label=\"Dismiss error\"\n >\n ✕\n </button>\n </div>\n );\n}\n\n// Code block component with syntax highlighting and copy button\ninterface CodeBlockProps {\n inline?: boolean;\n className?: string;\n children?: React.ReactNode;\n}\n\nfunction CodeBlock({ inline, className, children, ...props }: CodeBlockProps) {\n const [copied, setCopied] = useState(false);\n\n // Extract language from className (format: language-js, language-python, etc.)\n const match = /language-(\\w+)/.exec(className || '');\n const language = match ? match[1] : '';\n\n const codeString = String(children).replace(/\\n$/, '');\n\n const handleCopy = () => {\n navigator.clipboard.writeText(codeString);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n };\n\n // Inline code (backticks)\n if (inline) {\n return <code className={className} {...props}>{children}</code>;\n }\n\n // Code block with syntax highlighting\n return (\n <div style={{ position: 'relative', marginTop: '8px', marginBottom: '8px' }}>\n <button\n onClick={handleCopy}\n style={{\n position: 'absolute',\n top: '8px',\n right: '8px',\n padding: '4px 8px',\n background: copied ? '#28a745' : 'rgba(255, 255, 255, 0.1)',\n color: 'white',\n border: 'none',\n borderRadius: '4px',\n cursor: 'pointer',\n fontSize: '12px',\n zIndex: 1,\n transition: 'background 0.2s',\n }}\n aria-label=\"Copy code\"\n >\n {copied ? '✓ Copied!' : '📋 Copy'}\n </button>\n <SyntaxHighlighter\n language={language || 'text'}\n style={vscDarkPlus}\n customStyle={{\n borderRadius: '8px',\n padding: '16px',\n fontSize: '13px',\n marginTop: 0,\n marginBottom: 0,\n }}\n {...props}\n >\n {codeString}\n </SyntaxHighlighter>\n </div>\n );\n}\n\nexport function InAppAI({\n endpoint = 'http://localhost:3001',\n position = 'bottom-right',\n displayMode = 'popup',\n defaultFolded = false,\n theme = 'light',\n context,\n customStyles = {},\n tools = [],\n panelMinWidth = '20%',\n panelMaxWidth = '33.33%',\n panelDefaultWidth = '25%',\n onPanelResize\n}: InAppAIProps) {\n const [isOpen, setIsOpen] = useState(displayMode.startsWith('sidebar') || displayMode.startsWith('panel'));\n const [isFolded, setIsFolded] = useState(defaultFolded && (displayMode.startsWith('sidebar') || displayMode.startsWith('panel')));\n const [messages, setMessages] = useState<Message[]>([]);\n const [inputValue, setInputValue] = useState('');\n const [isLoading, setIsLoading] = useState(false);\n const [isConnected, setIsConnected] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [panelWidth, setPanelWidth] = useState(panelDefaultWidth);\n const [isResizing, setIsResizing] = useState(false);\n const messagesEndRef = useRef<HTMLDivElement>(null);\n const conversationId = useRef(`react-demo-${Date.now()}`);\n const resizeRef = useRef<HTMLDivElement>(null);\n const inputRef = useRef<HTMLInputElement>(null);\n\n const isSidebar = displayMode.startsWith('sidebar');\n const isPanel = displayMode.startsWith('panel');\n const isLeftSidebar = displayMode === 'sidebar-left';\n // const isRightSidebar = displayMode === 'sidebar-right';\n const isLeftPanel = displayMode === 'panel-left';\n // const isRightPanel = displayMode === 'panel-right';\n\n // For sidebar and panel mode, start open\n useEffect(() => {\n if (isSidebar || isPanel) {\n setIsOpen(true);\n }\n }, [isSidebar, isPanel]);\n\n // Panel resize handlers\n useEffect(() => {\n if (!isPanel || !isResizing) return;\n\n const handleMouseMove = (e: MouseEvent) => {\n const container = resizeRef.current?.parentElement;\n if (!container) return;\n\n const containerRect = container.getBoundingClientRect();\n let newWidth: number;\n\n if (isLeftPanel) {\n newWidth = e.clientX;\n } else {\n newWidth = containerRect.width - e.clientX;\n }\n\n // Convert to percentage\n const widthPercent = (newWidth / containerRect.width) * 100;\n\n // Parse min/max widths\n const minPercent = parseFloat(panelMinWidth);\n const maxPercent = parseFloat(panelMaxWidth);\n\n // Clamp width between min and max\n const clampedPercent = Math.max(minPercent, Math.min(maxPercent, widthPercent));\n const newWidthStr = `${clampedPercent}%`;\n\n setPanelWidth(newWidthStr);\n if (onPanelResize) {\n onPanelResize(newWidth);\n }\n };\n\n const handleMouseUp = () => {\n setIsResizing(false);\n };\n\n document.addEventListener('mousemove', handleMouseMove);\n document.addEventListener('mouseup', handleMouseUp);\n\n return () => {\n document.removeEventListener('mousemove', handleMouseMove);\n document.removeEventListener('mouseup', handleMouseUp);\n };\n }, [isResizing, isPanel, isLeftPanel, panelMinWidth, panelMaxWidth, onPanelResize]);\n\n // Check backend connection\n useEffect(() => {\n const checkConnection = async () => {\n try {\n const response = await fetch(`${endpoint}/health`);\n if (response.ok) {\n setIsConnected(true);\n setError(null);\n } else {\n setError('Backend not responding');\n }\n } catch (err) {\n setError('Failed to connect to backend');\n setIsConnected(false);\n }\n };\n\n checkConnection();\n const interval = setInterval(checkConnection, 30000); // Check every 30s\n return () => clearInterval(interval);\n }, [endpoint]);\n\n // Auto-scroll to bottom\n useEffect(() => {\n messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });\n }, [messages]);\n\n // Refocus input after loading completes\n useEffect(() => {\n if (!isLoading && isConnected) {\n // Small delay to ensure DOM has updated\n setTimeout(() => {\n inputRef.current?.focus();\n }, 100);\n }\n }, [isLoading, isConnected]);\n\n const sendMessage = async () => {\n const message = inputValue.trim();\n if (!message || isLoading) return;\n\n // Add user message\n const userMessage: Message = {\n id: `${Date.now()}-user`,\n role: 'user',\n content: message,\n timestamp: new Date(),\n };\n\n setMessages(prev => [...prev, userMessage]);\n setInputValue('');\n setIsLoading(true);\n setError(null);\n\n try {\n // Helper to get fresh context (supports both static and function contexts)\n const getContext = () => typeof context === 'function' ? context() : context;\n\n // Prepare tool definitions (without handlers) for backend in OpenAI format\n const toolDefinitions = tools.map(({ name, description, parameters }) => ({\n type: 'function' as const,\n function: {\n name,\n description,\n parameters,\n },\n }));\n\n const response = await fetch(`${endpoint}/chat`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n message,\n conversationId: conversationId.current,\n context: getContext(),\n tools: toolDefinitions.length > 0 ? toolDefinitions : undefined,\n disableCache: false,\n }),\n });\n\n if (!response.ok) {\n throw new Error('Failed to get response');\n }\n\n const data = await response.json();\n\n // Check if AI returned tool calls\n if (data.toolCalls && data.toolCalls.length > 0) {\n // Execute tool handlers locally\n const results = await Promise.all(\n data.toolCalls.map(async (toolCall: any) => {\n // OpenAI format: {id, type, function: {name, arguments}}\n const toolName = toolCall.function?.name || toolCall.name;\n const toolArgs = toolCall.function?.arguments\n ? JSON.parse(toolCall.function.arguments)\n : toolCall.parameters;\n\n const tool = tools.find(t => t.name === toolName);\n if (!tool) {\n return { success: false, error: `Tool '${toolName}' not found` };\n }\n try {\n const result = await Promise.resolve(tool.handler(toolArgs));\n return result;\n } catch (error: any) {\n console.error(`Tool '${tool.name}' failed:`, error);\n return { success: false, error: error.message };\n }\n })\n );\n\n // Send tool results back to AI for natural language response\n const toolResultsMessage = results\n .map((r: any, idx: any) => {\n const toolCall = data.toolCalls[idx];\n const toolName = toolCall.function?.name || toolCall.name;\n return `Tool \"${toolName}\" result: ${JSON.stringify(r)}`;\n })\n .join('\\n');\n\n // IMPORTANT: Get fresh context after tool execution\n // Tool handlers may have updated state (e.g., added/completed todos)\n // By calling getContext() again, we ensure the AI sees the updated state\n const followUpResponse = await fetch(`${endpoint}/chat`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n message: toolResultsMessage,\n conversationId: conversationId.current,\n context: getContext(), // Fresh context after tool execution\n disableCache: false,\n }),\n });\n\n if (!followUpResponse.ok) {\n throw new Error('Failed to get AI response for tool results');\n }\n\n const followUpData = await followUpResponse.json();\n\n const assistantMessage: Message = {\n id: `${Date.now()}-assistant`,\n role: 'assistant',\n content: followUpData.message || 'I executed the tools successfully.',\n timestamp: new Date(),\n usage: followUpData.usage,\n };\n\n setMessages(prev => [...prev, assistantMessage]);\n } else {\n const assistantMessage: Message = {\n id: `${Date.now()}-assistant`,\n role: 'assistant',\n content: data.message,\n timestamp: new Date(),\n usage: data.usage,\n };\n\n setMessages(prev => [...prev, assistantMessage]);\n }\n } catch (err) {\n console.error('❌ Error:', err);\n setError(err instanceof Error ? err.message : 'Unknown error');\n } finally {\n setIsLoading(false);\n }\n };\n\n const handleKeyPress = (e: React.KeyboardEvent) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault();\n sendMessage();\n }\n };\n\n const clearMessages = () => {\n setMessages([]);\n conversationId.current = `react-demo-${Date.now()}`;\n };\n\n const toggleFolded = () => {\n setIsFolded(!isFolded);\n };\n\n const positionClass = `inapp-ai-${position}`;\n // Don't add a theme class for 'light' since it's the default\n const themeClass = theme && theme !== 'light' ? `inapp-ai-theme-${theme}` : '';\n const modeClass = isSidebar\n ? `inapp-ai-sidebar inapp-ai-${displayMode}`\n : isPanel\n ? `inapp-ai-panel inapp-ai-${displayMode}`\n : 'inapp-ai-popup';\n const foldedClass = isFolded ? 'inapp-ai-folded' : '';\n\n // Build custom button style\n const buttonStyle: React.CSSProperties = {\n ...(customStyles.buttonBackgroundColor && { background: customStyles.buttonBackgroundColor }),\n ...(customStyles.buttonTextColor && { color: customStyles.buttonTextColor }),\n ...(customStyles.buttonSize && {\n width: customStyles.buttonSize,\n height: customStyles.buttonSize,\n fontSize: `calc(${customStyles.buttonSize} * 0.5)`\n }),\n ...(customStyles.buttonBorderRadius && { borderRadius: customStyles.buttonBorderRadius }),\n ...(customStyles.boxShadow && { boxShadow: customStyles.boxShadow }),\n };\n\n // Build custom window style\n const windowStyle: React.CSSProperties = {\n ...(customStyles.windowWidth && !isSidebar && !isPanel && { width: customStyles.windowWidth }),\n ...(customStyles.windowHeight && !isSidebar && !isPanel && { height: customStyles.windowHeight }),\n ...(customStyles.windowBorderRadius && { borderRadius: customStyles.windowBorderRadius }),\n ...(customStyles.fontFamily && { fontFamily: customStyles.fontFamily }),\n ...(customStyles.fontSize && { fontSize: customStyles.fontSize }),\n ...(customStyles.sidebarWidth && isSidebar && !isFolded && { width: customStyles.sidebarWidth }),\n ...(customStyles.sidebarFoldedWidth && isSidebar && isFolded && { width: customStyles.sidebarFoldedWidth }),\n ...(isPanel && { width: panelWidth }),\n };\n\n return (\n <>\n {/* Chat Button (only for popup mode) */}\n {!isSidebar && !isPanel && (\n <button\n className={`inapp-ai-button ${positionClass} ${themeClass}`}\n style={buttonStyle}\n onClick={() => setIsOpen(!isOpen)}\n aria-label={isOpen ? \"Close AI Assistant\" : \"Open AI Assistant\"}\n aria-expanded={isOpen}\n aria-haspopup=\"dialog\"\n tabIndex={0}\n >\n {isOpen ? '✕' : (customStyles.buttonIcon || '🤖')}\n {!isConnected && (\n <span\n className=\"inapp-ai-offline-indicator\"\n role=\"status\"\n aria-label=\"Backend disconnected\"\n />\n )}\n </button>\n )}\n\n {/* Chat Window */}\n {isOpen && (\n <div\n ref={resizeRef}\n role=\"dialog\"\n aria-label=\"AI Assistant Chat\"\n aria-modal={!isSidebar && !isPanel ? \"true\" : undefined}\n className={`inapp-ai-window ${modeClass} ${isSidebar || isPanel ? '' : positionClass} ${themeClass} ${foldedClass}`}\n style={windowStyle}\n >\n {/* Resize Handle for Panel */}\n {isPanel && (\n <div\n className={`inapp-ai-resize-handle ${isLeftPanel ? 'inapp-ai-resize-handle-right' : 'inapp-ai-resize-handle-left'}`}\n onMouseDown={() => setIsResizing(true)}\n title=\"Drag to resize\"\n />\n )}\n\n {/* Folded State Content */}\n {(isSidebar || isPanel) && isFolded ? (\n <div\n className=\"inapp-ai-folded-content\"\n onClick={toggleFolded}\n style={{ cursor: 'pointer' }}\n title=\"Click to unfold\"\n >\n <div className=\"inapp-ai-folded-icon\">\n {customStyles.buttonIcon || '🤖'}\n </div>\n <div className=\"inapp-ai-folded-text\">\n AI\n </div>\n {messages.length > 0 && (\n <div className=\"inapp-ai-message-count\">\n {messages.length}\n </div>\n )}\n </div>\n ) : (\n <>\n {/* Header */}\n <div className=\"inapp-ai-header\" style={{\n ...(customStyles.headerBackground && { background: customStyles.headerBackground }),\n ...(customStyles.headerTextColor && { color: customStyles.headerTextColor }),\n }}>\n <div className=\"inapp-ai-header-title\">\n <span className=\"inapp-ai-header-icon\">{customStyles.buttonIcon || '🤖'}</span>\n <div>\n <h3>{customStyles.headerTitle || 'AI Assistant'}</h3>\n <p>\n {isConnected ? (\n <span className=\"inapp-ai-status-connected\">\n <span className=\"inapp-ai-status-dot\" />\n Connected\n </span>\n ) : (\n <span className=\"inapp-ai-status-disconnected\">\n <span className=\"inapp-ai-status-dot\" />\n Disconnected\n </span>\n )}\n </p>\n </div>\n </div>\n {/* Fold button for panels (in header top right) */}\n {(isSidebar || isPanel) && (\n <button\n className=\"inapp-ai-header-fold-btn\"\n onClick={toggleFolded}\n aria-label={isFolded ? `Unfold ${isSidebar ? 'sidebar' : 'panel'}` : `Fold ${isSidebar ? 'sidebar' : 'panel'}`}\n title={isFolded ? `Unfold ${isSidebar ? 'sidebar' : 'panel'}` : `Fold ${isSidebar ? 'sidebar' : 'panel'}`}\n >\n {(isLeftSidebar || isLeftPanel) ? '◀' : '▶'}\n </button>\n )}\n {/* Close button for popup mode */}\n {!isSidebar && !isPanel && (\n <button\n className=\"inapp-ai-close-btn\"\n onClick={() => setIsOpen(false)}\n aria-label=\"Close\"\n >\n ✕\n </button>\n )}\n </div>\n\n {/* Error Banner */}\n {error && (\n <ErrorMessage error={error} onDismiss={() => setError(null)} />\n )}\n\n {/* Messages */}\n <div\n className=\"inapp-ai-messages\"\n role=\"log\"\n aria-live=\"polite\"\n aria-label=\"Chat messages\"\n >\n {messages.length === 0 ? (\n <div className=\"inapp-ai-empty-state\" role=\"status\">\n <div className=\"inapp-ai-empty-icon\" aria-hidden=\"true\">💬</div>\n <h4>Start a conversation</h4>\n <p>Ask me anything! I'm powered by OpenAI.</p>\n </div>\n ) : (\n messages.map((msg) => (\n <div\n key={msg.id}\n className={`inapp-ai-message inapp-ai-message-${msg.role}`}\n role=\"article\"\n aria-label={`${msg.role === 'user' ? 'User' : 'Assistant'} message`}\n >\n <div className=\"inapp-ai-message-icon\" aria-hidden=\"true\">\n {msg.role === 'user' ? '👤' : '🤖'}\n </div>\n <div className=\"inapp-ai-message-content\">\n <div className=\"inapp-ai-message-text\" style={{\n ...(msg.role === 'user' && customStyles.userMessageBackground && { background: customStyles.userMessageBackground }),\n ...(msg.role === 'user' && customStyles.userMessageColor && { color: customStyles.userMessageColor }),\n ...(msg.role === 'assistant' && customStyles.assistantMessageBackground && { background: customStyles.assistantMessageBackground }),\n ...(msg.role === 'assistant' && customStyles.assistantMessageColor && { color: customStyles.assistantMessageColor }),\n ...(customStyles.borderRadius && { borderRadius: customStyles.borderRadius }),\n }}>\n {msg.role === 'assistant' ? (\n <ReactMarkdown\n components={{\n code: CodeBlock as any,\n }}\n >\n {msg.content}\n </ReactMarkdown>\n ) : (\n msg.content\n )}\n </div>\n <div className=\"inapp-ai-message-time\">\n {msg.timestamp.toLocaleTimeString()}\n {msg.usage && (\n <span className=\"inapp-ai-message-tokens\">\n {' • '}{msg.usage.totalTokens} tokens\n </span>\n )}\n </div>\n </div>\n </div>\n ))\n )}\n {isLoading && (\n <div className=\"inapp-ai-message inapp-ai-message-assistant\">\n <div className=\"inapp-ai-message-icon\">\n <div style={{ animation: 'pulse 2s infinite' }}>🤖</div>\n </div>\n <div className=\"inapp-ai-message-content\">\n <div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>\n <div className=\"inapp-ai-typing-indicator\">\n <span></span>\n <span></span>\n <span></span>\n </div>\n <LoadingSkeleton />\n </div>\n </div>\n </div>\n )}\n <div ref={messagesEndRef} />\n </div>\n\n {/* Input Area */}\n <div className=\"inapp-ai-input-area\" role=\"form\" aria-label=\"Message input\">\n {messages.length > 0 && (\n <button\n className=\"inapp-ai-clear-btn\"\n onClick={clearMessages}\n disabled={isLoading}\n aria-label=\"Clear conversation history\"\n tabIndex={0}\n >\n <span aria-hidden=\"true\">🗑️</span> Clear\n </button>\n )}\n <div className=\"inapp-ai-input-wrapper\">\n <input\n ref={inputRef}\n type=\"text\"\n className=\"inapp-ai-input\"\n placeholder={customStyles.inputPlaceholder || \"Type your message...\"}\n value={inputValue}\n onChange={(e) => setInputValue(e.target.value)}\n onKeyPress={handleKeyPress}\n disabled={isLoading || !isConnected}\n aria-label=\"Message input\"\n aria-describedby=\"send-hint\"\n tabIndex={0}\n style={{\n ...(customStyles.inputBackground && { background: customStyles.inputBackground }),\n ...(customStyles.inputBorderColor && { borderColor: customStyles.inputBorderColor }),\n ...(customStyles.inputTextColor && { color: customStyles.inputTextColor }),\n }}\n />\n <button\n className=\"inapp-ai-send-btn\"\n onClick={sendMessage}\n disabled={isLoading || !isConnected || !inputValue.trim()}\n aria-label=\"Send message\"\n tabIndex={0}\n >\n <span aria-hidden=\"true\">{isLoading ? '⏳' : '⬆'}</span>\n <span className=\"sr-only\">\n {isLoading ? 'Sending...' : 'Send message'}\n </span>\n </button>\n <span id=\"send-hint\" className=\"sr-only\">\n Press Enter to send\n </span>\n </div>\n </div>\n </>\n )}\n </div>\n )}\n </>\n );\n}\n"],"mappings":"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","names":["useState","useEffect","useRef","ReactMarkdown","SyntaxHighlighter","vscDarkPlus","Fragment","jsx","jsxs","LoadingSkeleton","ErrorMessage","error","onDismiss","errorInfo","msg","CodeBlock","inline","className","children","props","copied","setCopied","useState","match","language","codeString","handleCopy","SyntaxHighlighter","vscDarkPlus","InAppAI","endpoint","position","displayMode","defaultFolded","theme","context","customStyles","tools","panelMinWidth","panelMaxWidth","panelDefaultWidth","onPanelResize","isOpen","setIsOpen","isFolded","setIsFolded","messages","setMessages","inputValue","setInputValue","isLoading","setIsLoading","isConnected","setIsConnected","setError","panelWidth","setPanelWidth","isResizing","setIsResizing","messagesEndRef","useRef","conversationId","resizeRef","inputRef","isSidebar","isPanel","isLeftSidebar","isLeftPanel","useEffect","handleMouseMove","e","container","containerRect","newWidth","widthPercent","minPercent","maxPercent","newWidthStr","handleMouseUp","checkConnection","interval","sendMessage","message","userMessage","prev","getContext","toolDefinitions","name","description","parameters","response","data","toolResultsMessage","toolCall","toolName","toolArgs","tool","t","r","idx","followUpResponse","followUpData","assistantMessage","err","handleKeyPress","clearMessages","toggleFolded","positionClass","themeClass","modeClass","foldedClass","buttonStyle","windowStyle","ReactMarkdown"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@inappai/react",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Beautiful, customizable AI chat component for React applications",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"module": "./dist/index.mjs",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.mjs",
|
|
12
|
+
"require": "./dist/index.js"
|
|
13
|
+
},
|
|
14
|
+
"./styles.css": "./dist/index.css"
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist"
|
|
18
|
+
],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "tsup",
|
|
21
|
+
"dev": "tsup --watch",
|
|
22
|
+
"type-check": "tsc --noEmit",
|
|
23
|
+
"clean": "rm -rf dist"
|
|
24
|
+
},
|
|
25
|
+
"keywords": [
|
|
26
|
+
"ai",
|
|
27
|
+
"react",
|
|
28
|
+
"chatbot",
|
|
29
|
+
"assistant",
|
|
30
|
+
"openai",
|
|
31
|
+
"anthropic",
|
|
32
|
+
"chat-ui",
|
|
33
|
+
"component"
|
|
34
|
+
],
|
|
35
|
+
"author": "InAppAI",
|
|
36
|
+
"license": "MIT",
|
|
37
|
+
"repository": {
|
|
38
|
+
"type": "git",
|
|
39
|
+
"url": "https://github.com/InAppAI/react.git",
|
|
40
|
+
"directory": "packages/inapp-ai-react"
|
|
41
|
+
},
|
|
42
|
+
"bugs": {
|
|
43
|
+
"url": "https://github.com/InAppAI/react/issues"
|
|
44
|
+
},
|
|
45
|
+
"homepage": "https://github.com/InAppAI/react#readme",
|
|
46
|
+
"peerDependencies": {
|
|
47
|
+
"react": "^18.0.0",
|
|
48
|
+
"react-dom": "^18.0.0"
|
|
49
|
+
},
|
|
50
|
+
"dependencies": {
|
|
51
|
+
"react-markdown": "^10.1.0",
|
|
52
|
+
"react-syntax-highlighter": "^16.1.0"
|
|
53
|
+
},
|
|
54
|
+
"devDependencies": {
|
|
55
|
+
"@types/react": "^18.2.55",
|
|
56
|
+
"@types/react-dom": "^18.2.19",
|
|
57
|
+
"@types/react-syntax-highlighter": "^15.5.13",
|
|
58
|
+
"react": "^18.2.0",
|
|
59
|
+
"react-dom": "^18.2.0",
|
|
60
|
+
"tsup": "^8.0.0",
|
|
61
|
+
"typescript": "^5.3.3"
|
|
62
|
+
}
|
|
63
|
+
}
|