@vezlo/assistant-chat 1.1.0 → 1.2.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 +22 -9
- package/lib/api/conversation.d.ts +1 -3
- package/lib/components/Widget.js +10 -10
- package/lib/components/ui/VezloFooter.js +6 -4
- package/lib/config/theme.d.ts +31 -0
- package/lib/config/theme.js +36 -1
- package/lib/types/index.d.ts +0 -3
- package/lib/utils/index.d.ts +0 -3
- package/lib/utils/index.js +0 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -20,6 +20,8 @@ A complete chat widget solution with both a React component library and standalo
|
|
|
20
20
|
- **Embed Code Generator**: Get ready-to-use embed codes
|
|
21
21
|
- **Docker Support**: Easy deployment with Docker Compose
|
|
22
22
|
- **Vercel Ready**: One-click deployment to Vercel
|
|
23
|
+
- **Shared Layout**: `MainLayout` + `Header` provide a consistent, Vercel-style shell across every page
|
|
24
|
+
- **Auth-Ready Context**: `AppProvider` exposes user/workspace state, token helpers, and `ProtectedRoute` support for future login flows
|
|
23
25
|
|
|
24
26
|
## Quick Start
|
|
25
27
|
|
|
@@ -65,6 +67,7 @@ npm run dev
|
|
|
65
67
|
- Live preview and playground
|
|
66
68
|
- Embed code generation
|
|
67
69
|
- Docker and Vercel deployment support
|
|
70
|
+
- Theme + widget matrices: see [`docs/THEME_WIDGET_CONFIG.md`](docs/THEME_WIDGET_CONFIG.md) for every field, color mapping tips, and widget overrides
|
|
68
71
|
|
|
69
72
|
## Prerequisites
|
|
70
73
|
|
|
@@ -103,8 +106,17 @@ npm publish # Publish to NPM
|
|
|
103
106
|
|
|
104
107
|
### App (Vercel)
|
|
105
108
|
|
|
106
|
-
####
|
|
107
|
-
[](https://vercel.com/marketplace/vezlo-assistant-chat)
|
|
111
|
+
|
|
112
|
+
The marketplace app deploys the frontend automatically, prompts you for the **Assistant Server URL** and optional **API key**, and ships both the chat UI and embeddable widget without any manual environment setup. After connecting your Vercel project you can immediately visit:
|
|
113
|
+
|
|
114
|
+
- Chat UI: `https://your-project.vercel.app/`
|
|
115
|
+
|
|
116
|
+
#### One-Click Deploy (GitHub Clone)
|
|
117
|
+
[](https://vercel.com/new/clone?repository-url=https://github.com/vezlo/assistant-chat&integration-ids=oac_ZKcos500xraYgL9hH2d3Bs3A)
|
|
118
|
+
|
|
119
|
+
This clones the repo into your GitHub account, spins up a new Vercel project using the default `main` branch, and links the same Vezlo integration so the Assistant Chat deployment can gather its Assistant Server URL and API key during setup.
|
|
108
120
|
|
|
109
121
|
#### Manual Vercel CLI Deployment
|
|
110
122
|
```bash
|
|
@@ -118,13 +130,6 @@ vercel
|
|
|
118
130
|
vercel env add VITE_ASSISTANT_SERVER_URL
|
|
119
131
|
vercel env add VITE_ASSISTANT_SERVER_API_KEY
|
|
120
132
|
|
|
121
|
-
# Optional environment variables
|
|
122
|
-
vercel env add VITE_DEFAULT_USER_UUID
|
|
123
|
-
vercel env add VITE_DEFAULT_COMPANY_UUID
|
|
124
|
-
vercel env add VITE_WIDGET_DEFAULT_THEME
|
|
125
|
-
vercel env add VITE_WIDGET_DEFAULT_POSITION
|
|
126
|
-
vercel env add VITE_WIDGET_DEFAULT_SIZE
|
|
127
|
-
|
|
128
133
|
# Deploy to production
|
|
129
134
|
vercel --prod
|
|
130
135
|
```
|
|
@@ -158,10 +163,18 @@ assistant-chat/
|
|
|
158
163
|
### How It Works
|
|
159
164
|
|
|
160
165
|
- **Same Widget Code**: Both the NPM package and standalone app use the same `Widget.tsx` component
|
|
166
|
+
- **Embed & Playground**: `WidgetPage.tsx` powers the iframe, embed script, and playground preview using that same component
|
|
161
167
|
- **NPM Package**: Publishes the widget component as a reusable library
|
|
162
168
|
- **Standalone App**: Uses the widget component directly for admin interface and playground
|
|
163
169
|
- **No Duplication**: Single source of truth for the widget component
|
|
164
170
|
|
|
171
|
+
## Layout & Auth Architecture
|
|
172
|
+
|
|
173
|
+
- `AppProvider` manages `user`, `workspace`, auth token, and exposes `login/logout` helpers plus `ProtectedRoute` for future API integration.
|
|
174
|
+
- `Header` & `MainLayout` deliver the new full-width, two-row dashboard shell (logo, workspace switcher, company badge, primary nav, profile dropdown).
|
|
175
|
+
- `ConfigPage` (dashboard) and every other route render inside `MainLayout`, so all future pages automatically inherit the header and spacing.
|
|
176
|
+
- `LoginPage` lives outside the layout and is already wired to `AppProvider`, making it ready for real authentication APIs.
|
|
177
|
+
|
|
165
178
|
## Architecture
|
|
166
179
|
|
|
167
180
|
```
|
package/lib/components/Widget.js
CHANGED
|
@@ -5,6 +5,7 @@ import { Send, X, MessageCircle, Bot, ThumbsUp, ThumbsDown } from 'lucide-react'
|
|
|
5
5
|
import { generateId, formatTimestamp } from '../utils/index.js';
|
|
6
6
|
import { VezloFooter } from './ui/VezloFooter.js';
|
|
7
7
|
import { createConversation, createUserMessage, generateAIResponse } from '../api/index.js';
|
|
8
|
+
import { THEME } from '../config/theme.js';
|
|
8
9
|
export function Widget({ config, isPlayground = false, onOpen, onClose, onMessage, onError, useShadowRoot = false, }) {
|
|
9
10
|
// Use defaultOpen from config, fallback to isPlayground for backward compatibility
|
|
10
11
|
const [isOpen, setIsOpen] = useState(config.defaultOpen ?? isPlayground);
|
|
@@ -62,12 +63,8 @@ export function Widget({ config, isPlayground = false, onOpen, onClose, onMessag
|
|
|
62
63
|
setIsCreatingConversation(true);
|
|
63
64
|
try {
|
|
64
65
|
// Create a new conversation
|
|
65
|
-
const userUuid = import.meta.env.VITE_DEFAULT_USER_UUID || 'user-' + generateId().substring(0, 8);
|
|
66
|
-
const companyUuid = import.meta.env.VITE_DEFAULT_COMPANY_UUID || 'company-' + generateId().substring(0, 8);
|
|
67
66
|
const conversation = await createConversation({
|
|
68
67
|
title: 'New Chat',
|
|
69
|
-
user_uuid: userUuid,
|
|
70
|
-
company_uuid: companyUuid,
|
|
71
68
|
}, config.apiUrl);
|
|
72
69
|
setConversationUuid(conversation.uuid);
|
|
73
70
|
console.log('[Widget] Conversation created:', conversation.uuid);
|
|
@@ -237,7 +234,7 @@ export function Widget({ config, isPlayground = false, onOpen, onClose, onMessag
|
|
|
237
234
|
} }), !isOpen && (_jsxs("div", { className: "relative animate-fadeIn", style: { pointerEvents: 'auto', width: 64, height: 64 }, children: [_jsx("div", { style: {
|
|
238
235
|
position: 'absolute',
|
|
239
236
|
inset: 0,
|
|
240
|
-
backgroundColor: config.themeColor ||
|
|
237
|
+
backgroundColor: config.themeColor || THEME.primary.hex,
|
|
241
238
|
borderRadius: 9999,
|
|
242
239
|
opacity: 0.2,
|
|
243
240
|
filter: 'blur(0px)'
|
|
@@ -247,7 +244,7 @@ export function Widget({ config, isPlayground = false, onOpen, onClose, onMessag
|
|
|
247
244
|
height: 64,
|
|
248
245
|
borderRadius: 9999,
|
|
249
246
|
color: '#fff',
|
|
250
|
-
background: `linear-gradient(135deg, ${config.themeColor}, ${config.themeColor}dd)`,
|
|
247
|
+
background: `linear-gradient(135deg, ${config.themeColor || THEME.primary.hex}, ${config.themeColor || THEME.primary.hex}dd)`,
|
|
251
248
|
boxShadow: '0 10px 25px rgba(0,0,0,0.20)',
|
|
252
249
|
display: 'flex',
|
|
253
250
|
alignItems: 'center',
|
|
@@ -263,18 +260,21 @@ export function Widget({ config, isPlayground = false, onOpen, onClose, onMessag
|
|
|
263
260
|
pointerEvents: 'auto',
|
|
264
261
|
width: (config.size && config.size.width) ? config.size.width : 420,
|
|
265
262
|
height: (config.size && config.size.height) ? config.size.height : 600
|
|
266
|
-
}, children: [_jsxs("div", { className: "text-white p-4 flex justify-between items-center relative overflow-hidden", style: { background: `linear-gradient(to right, ${config.themeColor}, ${config.themeColor}dd, ${config.themeColor}bb)`, color: '#fff' }, children: [_jsxs("div", { className: "absolute inset-0 opacity-10", children: [_jsx("div", { className: "absolute top-0 left-0 w-full h-full bg-gradient-to-br from-white/20 to-transparent" }), _jsx("div", { className: "absolute bottom-0 right-0 w-32 h-32 bg-white/10 rounded-full -translate-y-8 translate-x-8" })] }), _jsxs("div", { className: "flex items-center gap-3 relative z-10", children: [_jsx("div", { className: "w-
|
|
263
|
+
}, children: [_jsxs("div", { className: "text-white p-4 flex justify-between items-center relative overflow-hidden", style: { background: `linear-gradient(to right, ${config.themeColor || THEME.primary.hex}, ${config.themeColor || THEME.primary.hex}dd, ${config.themeColor || THEME.primary.hex}bb)`, color: '#fff' }, children: [_jsxs("div", { className: "absolute inset-0 opacity-10", children: [_jsx("div", { className: "absolute top-0 left-0 w-full h-full bg-gradient-to-br from-white/20 to-transparent" }), _jsx("div", { className: "absolute bottom-0 right-0 w-32 h-32 bg-white/10 rounded-full -translate-y-8 translate-x-8" })] }), _jsxs("div", { className: "flex items-center gap-3 relative z-10", children: [_jsx("div", { className: "w-12 h-12 bg-white/20 rounded-2xl flex items-center justify-center backdrop-blur-sm flex-shrink-0", children: _jsx(Bot, { className: "w-6 h-6 text-white" }) }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("h3", { className: "font-semibold text-lg leading-tight truncate", children: config.title }), _jsxs("div", { className: "flex items-center gap-1.5 mt-0.5", children: [_jsx("div", { className: "w-2 h-2 bg-green-400 rounded-full animate-pulse flex-shrink-0" }), _jsxs("p", { className: "text-xs text-white/90 truncate", children: ["Online \u2022 ", config.subtitle] })] })] })] }), _jsx("button", { onClick: handleCloseWidget, className: "hover:bg-white/20 rounded-lg p-2 transition-all duration-200 hover:scale-110 relative z-10", children: _jsx(X, { className: "w-5 h-5" }) })] }), _jsxs("div", { className: "flex-1 overflow-y-auto p-4 space-y-4 bg-gradient-to-b from-gray-50 to-white", children: [messages.map((message, index) => (_jsxs("div", { className: `flex ${message.role === 'user' ? 'justify-end' : 'justify-start'} animate-fadeIn`, style: { animationDelay: `${index * 0.1}s` }, children: [message.role === 'assistant' && (_jsx("div", { className: "w-8 h-8 bg-emerald-50 rounded-full flex items-center justify-center flex-shrink-0 mt-1 mr-2 border border-emerald-100", children: _jsx(Bot, { className: "w-4 h-4 text-emerald-600" }) })), _jsxs("div", { className: "flex flex-col max-w-[75%]", children: [_jsx("div", { className: `rounded-2xl px-4 py-3 shadow-sm transition-all duration-200 hover:shadow-md ${message.role === 'user'
|
|
267
264
|
? 'text-white'
|
|
268
265
|
: 'bg-white text-gray-900 border border-gray-200'}`, style: {
|
|
269
|
-
backgroundColor: message.role === 'user' ? config.themeColor : undefined,
|
|
266
|
+
backgroundColor: message.role === 'user' ? (config.themeColor || THEME.primary.hex) : undefined,
|
|
270
267
|
boxShadow: message.role === 'user'
|
|
271
|
-
? `0 4px 12px ${config.themeColor}4D` // 4D is ~30% opacity
|
|
268
|
+
? `0 4px 12px ${(config.themeColor || THEME.primary.hex)}4D` // 4D is ~30% opacity
|
|
272
269
|
: '0 2px 8px rgba(0, 0, 0, 0.1)'
|
|
273
270
|
}, children: _jsx("p", { className: "text-sm whitespace-pre-wrap break-words leading-relaxed", children: message.content }) }), _jsxs("div", { className: "flex items-center justify-between mt-1", children: [_jsx("p", { className: `text-xs ${message.role === 'user' ? 'text-emerald-100' : 'text-gray-500'}`, children: formatTimestamp(message.timestamp) }), message.role === 'assistant' && (_jsxs("div", { className: "flex items-center gap-1 ml-2", children: [_jsx("button", { onClick: () => handleFeedback(message.id, 'like'), className: `p-1 rounded transition-all duration-200 hover:scale-110 cursor-pointer ${messageFeedback[message.id] === 'like'
|
|
274
271
|
? 'text-green-600'
|
|
275
272
|
: 'text-gray-400 hover:text-green-600'}`, children: _jsx(ThumbsUp, { className: `w-4 h-4 ${messageFeedback[message.id] === 'like' ? 'fill-current' : ''}` }) }), _jsx("button", { onClick: () => handleFeedback(message.id, 'dislike'), className: `p-1 rounded transition-all duration-200 hover:scale-110 cursor-pointer ${messageFeedback[message.id] === 'dislike'
|
|
276
273
|
? 'text-red-600'
|
|
277
|
-
: 'text-gray-400 hover:text-red-600'}`, children: _jsx(ThumbsDown, { className: `w-4 h-4 ${messageFeedback[message.id] === 'dislike' ? 'fill-current' : ''}` }) })] }))] })] })] }, message.id))), streamingMessage && (_jsxs("div", { className: "flex justify-start animate-fadeIn", children: [_jsx("div", { className: "w-8 h-8 bg-emerald-
|
|
274
|
+
: 'text-gray-400 hover:text-red-600'}`, children: _jsx(ThumbsDown, { className: `w-4 h-4 ${messageFeedback[message.id] === 'dislike' ? 'fill-current' : ''}` }) })] }))] })] })] }, message.id))), streamingMessage && (_jsxs("div", { className: "flex justify-start animate-fadeIn", children: [_jsx("div", { className: "w-8 h-8 bg-emerald-50 rounded-full flex items-center justify-center flex-shrink-0 mt-1 mr-2 border border-emerald-100", children: _jsx(Bot, { className: "w-4 h-4 text-emerald-600" }) }), _jsx("div", { className: "flex flex-col max-w-[75%]", children: _jsx("div", { className: "bg-white text-gray-900 border border-gray-200 rounded-2xl px-4 py-3 shadow-sm", children: _jsxs("p", { className: "text-sm whitespace-pre-wrap break-words leading-relaxed", style: { color: '#111827' }, children: [streamingMessage, _jsx("span", { style: { display: 'inline-block', animation: 'vezloCaretBlink 1s steps(1, end) infinite' }, children: "|" })] }) }) })] })), isLoading && (_jsx("div", { className: "flex justify-start animate-fadeIn", children: _jsx("div", { className: "bg-white border border-gray-200 rounded-2xl px-4 py-3 flex items-center gap-3 shadow-sm", children: _jsxs("div", { className: "flex gap-1", style: { display: 'flex', gap: '4px' }, children: [_jsx("span", { style: { width: 8, height: 8, borderRadius: 9999, backgroundColor: config.themeColor || THEME.primary.hex, display: 'inline-block', animation: 'vezloDotPulse 1s infinite ease-in-out', animationDelay: '0s' } }), _jsx("span", { style: { width: 8, height: 8, borderRadius: 9999, backgroundColor: config.themeColor || THEME.primary.hex, display: 'inline-block', animation: 'vezloDotPulse 1s infinite ease-in-out', animationDelay: '0.15s' } }), _jsx("span", { style: { width: 8, height: 8, borderRadius: 9999, backgroundColor: config.themeColor || THEME.primary.hex, display: 'inline-block', animation: 'vezloDotPulse 1s infinite ease-in-out', animationDelay: '0.3s' } })] }) }) })), _jsx("div", { ref: messagesEndRef })] }), _jsx("div", { className: "border-t border-gray-200 p-4 bg-white", children: _jsxs("div", { className: "flex gap-3", children: [_jsx("input", { type: "text", value: input, onChange: (e) => setInput(e.target.value), onKeyPress: handleKeyPress, placeholder: config.placeholder, disabled: isLoading, className: "flex-1 px-4 py-3 border border-gray-300 rounded-2xl focus:outline-none focus:ring-2 focus:ring-emerald-500 focus:border-transparent disabled:bg-gray-100 disabled:cursor-not-allowed text-sm transition-all duration-200 placeholder:text-gray-400" }), _jsx("button", { onClick: handleSendMessage, disabled: !input.trim() || isLoading, className: "text-white px-4 py-3 rounded-2xl transition-all duration-200 disabled:bg-gray-300 disabled:cursor-not-allowed flex items-center justify-center shadow-lg hover:shadow-xl disabled:shadow-none transform hover:scale-105 disabled:scale-100 min-w-[48px]", style: {
|
|
275
|
+
background: `linear-gradient(to right, ${config.themeColor || THEME.primary.hex}, ${config.themeColor || THEME.primary.hex}dd)`,
|
|
276
|
+
opacity: (!input.trim() || isLoading) ? 0.6 : 1
|
|
277
|
+
}, children: _jsx(Send, { className: "w-4 h-4" }) })] }) }), _jsx("div", { className: "border-t border-gray-200 px-4 bg-gradient-to-r from-gray-50 to-white", style: { minHeight: 52 }, children: _jsx(VezloFooter, { size: "sm" }) })] }))] }));
|
|
278
278
|
if (useShadowRoot) {
|
|
279
279
|
// Ensure host exists in DOM
|
|
280
280
|
return (_jsx("div", { ref: hostRef, style: { all: 'initial' }, children: shadowReady && shadowMountRef.current ? createPortal(content, shadowMountRef.current) : null }));
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
3
|
-
export function VezloFooter({ size = '
|
|
4
|
-
const iconSize = size === 'sm' ? 'w-3 h-3' : 'w-4 h-4';
|
|
2
|
+
import { Zap } from 'lucide-react';
|
|
3
|
+
export function VezloFooter({ size = 'sm' }) {
|
|
5
4
|
const textSize = size === 'sm' ? 'text-xs' : 'text-sm';
|
|
6
|
-
|
|
5
|
+
const logoHeight = size === 'sm' ? 48 : 68;
|
|
6
|
+
const iconSize = size === 'sm' ? 'w-4 h-4' : 'w-5 h-5';
|
|
7
|
+
const gapClass = 'gap-1';
|
|
8
|
+
return (_jsxs("div", { className: `flex items-center justify-center ${gapClass}`, children: [_jsx("span", { className: `${textSize} text-gray-600 font-medium`, children: "Powered by" }), _jsx(Zap, { className: `${iconSize} flex-shrink-0 -mr-1`, style: { color: '#f5c518' } }), _jsx("img", { src: "/assets/vezlo.png", alt: "Vezlo", style: { height: `${logoHeight}px`, width: 'auto' }, className: "object-contain" })] }));
|
|
7
9
|
}
|
package/lib/config/theme.d.ts
CHANGED
|
@@ -6,6 +6,9 @@ export declare const THEME: {
|
|
|
6
6
|
readonly primary: {
|
|
7
7
|
readonly hex: "#059669";
|
|
8
8
|
readonly tailwind: "emerald";
|
|
9
|
+
readonly darker: "#047857";
|
|
10
|
+
readonly lighter: "#10b981";
|
|
11
|
+
readonly lightest: "#d1fae5";
|
|
9
12
|
};
|
|
10
13
|
readonly colors: {
|
|
11
14
|
readonly bg: "bg-emerald-600";
|
|
@@ -18,6 +21,34 @@ export declare const THEME: {
|
|
|
18
21
|
readonly border: "border-emerald-600";
|
|
19
22
|
readonly borderLight: "border-emerald-200";
|
|
20
23
|
};
|
|
24
|
+
readonly typography: {
|
|
25
|
+
readonly fontFamily: "system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif";
|
|
26
|
+
readonly heading: {
|
|
27
|
+
readonly weight: "600";
|
|
28
|
+
readonly size: {
|
|
29
|
+
readonly sm: "0.875rem";
|
|
30
|
+
readonly md: "1rem";
|
|
31
|
+
readonly lg: "1.125rem";
|
|
32
|
+
readonly xl: "1.25rem";
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
readonly body: {
|
|
36
|
+
readonly weight: "400";
|
|
37
|
+
readonly size: {
|
|
38
|
+
readonly sm: "0.75rem";
|
|
39
|
+
readonly md: "0.875rem";
|
|
40
|
+
readonly lg: "1rem";
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
readonly spacing: {
|
|
45
|
+
readonly xs: "0.5rem";
|
|
46
|
+
readonly sm: "0.75rem";
|
|
47
|
+
readonly md: "1rem";
|
|
48
|
+
readonly lg: "1.5rem";
|
|
49
|
+
readonly xl: "2rem";
|
|
50
|
+
};
|
|
21
51
|
};
|
|
22
52
|
export declare const getButtonGradient: (color?: string) => string;
|
|
23
53
|
export declare const getHeaderGradient: (color?: string) => string;
|
|
54
|
+
export declare const getHoverColor: () => "#047857";
|
package/lib/config/theme.js
CHANGED
|
@@ -3,10 +3,14 @@
|
|
|
3
3
|
* Change these values to update colors across the entire application
|
|
4
4
|
*/
|
|
5
5
|
export const THEME = {
|
|
6
|
-
// Primary brand color (emerald)
|
|
6
|
+
// Primary brand color (emerald/teal)
|
|
7
7
|
primary: {
|
|
8
8
|
hex: '#059669',
|
|
9
9
|
tailwind: 'emerald',
|
|
10
|
+
// Color variants for different use cases
|
|
11
|
+
darker: '#047857', // For hover states
|
|
12
|
+
lighter: '#10b981', // For accents
|
|
13
|
+
lightest: '#d1fae5', // For backgrounds
|
|
10
14
|
},
|
|
11
15
|
// Tailwind color variants
|
|
12
16
|
colors: {
|
|
@@ -20,6 +24,35 @@ export const THEME = {
|
|
|
20
24
|
border: 'border-emerald-600',
|
|
21
25
|
borderLight: 'border-emerald-200',
|
|
22
26
|
},
|
|
27
|
+
// Typography
|
|
28
|
+
typography: {
|
|
29
|
+
fontFamily: 'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
|
|
30
|
+
heading: {
|
|
31
|
+
weight: '600',
|
|
32
|
+
size: {
|
|
33
|
+
sm: '0.875rem',
|
|
34
|
+
md: '1rem',
|
|
35
|
+
lg: '1.125rem',
|
|
36
|
+
xl: '1.25rem',
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
body: {
|
|
40
|
+
weight: '400',
|
|
41
|
+
size: {
|
|
42
|
+
sm: '0.75rem',
|
|
43
|
+
md: '0.875rem',
|
|
44
|
+
lg: '1rem',
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
// Spacing (for consistency)
|
|
49
|
+
spacing: {
|
|
50
|
+
xs: '0.5rem',
|
|
51
|
+
sm: '0.75rem',
|
|
52
|
+
md: '1rem',
|
|
53
|
+
lg: '1.5rem',
|
|
54
|
+
xl: '2rem',
|
|
55
|
+
},
|
|
23
56
|
};
|
|
24
57
|
// Helper function to get gradient for buttons
|
|
25
58
|
export const getButtonGradient = (color = THEME.primary.hex) => {
|
|
@@ -29,3 +62,5 @@ export const getButtonGradient = (color = THEME.primary.hex) => {
|
|
|
29
62
|
export const getHeaderGradient = (color = THEME.primary.hex) => {
|
|
30
63
|
return `linear-gradient(to right, ${color}, ${color}dd, ${color}bb)`;
|
|
31
64
|
};
|
|
65
|
+
// Helper function to get darker shade for hover states
|
|
66
|
+
export const getHoverColor = () => THEME.primary.darker;
|
package/lib/types/index.d.ts
CHANGED
|
@@ -46,9 +46,6 @@ export interface WidgetProps {
|
|
|
46
46
|
export interface EnvConfig {
|
|
47
47
|
VITE_ASSISTANT_SERVER_URL: string;
|
|
48
48
|
VITE_ASSISTANT_SERVER_API_KEY: string;
|
|
49
|
-
VITE_WIDGET_DEFAULT_THEME: 'light' | 'dark';
|
|
50
|
-
VITE_WIDGET_DEFAULT_POSITION: string;
|
|
51
|
-
VITE_WIDGET_DEFAULT_SIZE: string;
|
|
52
49
|
VITE_DEV_MODE: boolean;
|
|
53
50
|
VITE_DEBUG_MODE: boolean;
|
|
54
51
|
}
|
package/lib/utils/index.d.ts
CHANGED
|
@@ -10,9 +10,6 @@ export declare function parseSize(sizeString: string): {
|
|
|
10
10
|
export declare function getEnvConfig(): {
|
|
11
11
|
VITE_ASSISTANT_SERVER_URL: any;
|
|
12
12
|
VITE_ASSISTANT_SERVER_API_KEY: any;
|
|
13
|
-
VITE_WIDGET_DEFAULT_THEME: "light" | "dark";
|
|
14
|
-
VITE_WIDGET_DEFAULT_POSITION: any;
|
|
15
|
-
VITE_WIDGET_DEFAULT_SIZE: any;
|
|
16
13
|
VITE_DEV_MODE: boolean;
|
|
17
14
|
VITE_DEBUG_MODE: boolean;
|
|
18
15
|
};
|
package/lib/utils/index.js
CHANGED
|
@@ -32,9 +32,6 @@ export function getEnvConfig() {
|
|
|
32
32
|
return {
|
|
33
33
|
VITE_ASSISTANT_SERVER_URL: import.meta.env.VITE_ASSISTANT_SERVER_URL || 'http://localhost:3000',
|
|
34
34
|
VITE_ASSISTANT_SERVER_API_KEY: import.meta.env.VITE_ASSISTANT_SERVER_API_KEY || '',
|
|
35
|
-
VITE_WIDGET_DEFAULT_THEME: import.meta.env.VITE_WIDGET_DEFAULT_THEME || 'light',
|
|
36
|
-
VITE_WIDGET_DEFAULT_POSITION: import.meta.env.VITE_WIDGET_DEFAULT_POSITION || 'bottom-right',
|
|
37
|
-
VITE_WIDGET_DEFAULT_SIZE: import.meta.env.VITE_WIDGET_DEFAULT_SIZE || '350x500',
|
|
38
35
|
VITE_DEV_MODE: import.meta.env.VITE_DEV_MODE === 'true',
|
|
39
36
|
VITE_DEBUG_MODE: import.meta.env.VITE_DEBUG_MODE === 'true'
|
|
40
37
|
};
|
package/package.json
CHANGED