@chatwidgetai/chat-widget 0.1.2 → 0.1.4
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/dist/components/ChatWidget.d.ts.map +1 -1
- package/dist/components/ChatWindow.d.ts.map +1 -1
- package/dist/components/MessageInput.d.ts +1 -0
- package/dist/components/MessageInput.d.ts.map +1 -1
- package/dist/components/MessageList.d.ts +1 -0
- package/dist/components/MessageList.d.ts.map +1 -1
- package/dist/hooks/useChat.d.ts.map +1 -1
- package/dist/index.esm.js +401 -42
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +401 -42
- package/dist/index.js.map +1 -1
- package/dist/types/index.d.ts +112 -5
- package/dist/types/index.d.ts.map +1 -1
- package/dist/utils/applyAppearanceStyles.d.ts +10 -0
- package/dist/utils/applyAppearanceStyles.d.ts.map +1 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -418,9 +418,16 @@ function useChat(options) {
|
|
|
418
418
|
// Load configuration on mount and hydrate with existing conversation if available
|
|
419
419
|
react.useEffect(() => {
|
|
420
420
|
let isMounted = true;
|
|
421
|
+
console.log('[useChat] Effect running, mounting component');
|
|
421
422
|
const initialize = async () => {
|
|
422
423
|
try {
|
|
424
|
+
console.log('[useChat] Fetching config...');
|
|
423
425
|
const config = await apiClient.current.getConfig();
|
|
426
|
+
console.log('[useChat] Config fetched successfully:', {
|
|
427
|
+
hasAppearance: !!config.appearance,
|
|
428
|
+
hasLightMode: !!config.appearance?.lightMode,
|
|
429
|
+
hasDarkMode: !!config.appearance?.darkMode,
|
|
430
|
+
});
|
|
424
431
|
const persistConversation = config.behavior.persistConversation ?? true;
|
|
425
432
|
let conversationId = '';
|
|
426
433
|
let messages = [];
|
|
@@ -439,8 +446,10 @@ function useChat(options) {
|
|
|
439
446
|
}
|
|
440
447
|
}
|
|
441
448
|
if (!isMounted) {
|
|
449
|
+
console.log('[useChat] Component unmounted, skipping state update');
|
|
442
450
|
return;
|
|
443
451
|
}
|
|
452
|
+
console.log('[useChat] Setting config in state');
|
|
444
453
|
setState(prev => ({
|
|
445
454
|
...prev,
|
|
446
455
|
config,
|
|
@@ -449,6 +458,7 @@ function useChat(options) {
|
|
|
449
458
|
}));
|
|
450
459
|
}
|
|
451
460
|
catch (error) {
|
|
461
|
+
console.error('[useChat] Error fetching config:', error);
|
|
452
462
|
if (!isMounted) {
|
|
453
463
|
return;
|
|
454
464
|
}
|
|
@@ -460,6 +470,7 @@ function useChat(options) {
|
|
|
460
470
|
};
|
|
461
471
|
initialize();
|
|
462
472
|
return () => {
|
|
473
|
+
console.log('[useChat] Effect cleanup, unmounting component');
|
|
463
474
|
isMounted = false;
|
|
464
475
|
};
|
|
465
476
|
}, [widgetId, apiKey, apiUrl, onError]);
|
|
@@ -2453,7 +2464,7 @@ function requireCjs$1 () {
|
|
|
2453
2464
|
};
|
|
2454
2465
|
Object.defineProperty(cjs$1, "__esModule", { value: true });
|
|
2455
2466
|
cjs$1.default = StyleToObject;
|
|
2456
|
-
|
|
2467
|
+
var inline_style_parser_1 = __importDefault(requireInlineStyleParser());
|
|
2457
2468
|
/**
|
|
2458
2469
|
* Parses inline style to object.
|
|
2459
2470
|
*
|
|
@@ -2469,17 +2480,17 @@ function requireCjs$1 () {
|
|
|
2469
2480
|
* ```
|
|
2470
2481
|
*/
|
|
2471
2482
|
function StyleToObject(style, iterator) {
|
|
2472
|
-
|
|
2483
|
+
var styleObject = null;
|
|
2473
2484
|
if (!style || typeof style !== 'string') {
|
|
2474
2485
|
return styleObject;
|
|
2475
2486
|
}
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
declarations.forEach((declaration)
|
|
2487
|
+
var declarations = (0, inline_style_parser_1.default)(style);
|
|
2488
|
+
var hasIterator = typeof iterator === 'function';
|
|
2489
|
+
declarations.forEach(function (declaration) {
|
|
2479
2490
|
if (declaration.type !== 'declaration') {
|
|
2480
2491
|
return;
|
|
2481
2492
|
}
|
|
2482
|
-
|
|
2493
|
+
var property = declaration.property, value = declaration.value;
|
|
2483
2494
|
if (hasIterator) {
|
|
2484
2495
|
iterator(property, value, declaration);
|
|
2485
2496
|
}
|
|
@@ -17520,7 +17531,8 @@ function footer(state) {
|
|
|
17520
17531
|
}
|
|
17521
17532
|
|
|
17522
17533
|
/**
|
|
17523
|
-
* @
|
|
17534
|
+
* @typedef {import('unist').Node} Node
|
|
17535
|
+
* @typedef {import('unist').Parent} Parent
|
|
17524
17536
|
*/
|
|
17525
17537
|
|
|
17526
17538
|
|
|
@@ -17568,11 +17580,7 @@ const convert =
|
|
|
17568
17580
|
}
|
|
17569
17581
|
|
|
17570
17582
|
if (typeof test === 'object') {
|
|
17571
|
-
return Array.isArray(test)
|
|
17572
|
-
? anyFactory(test)
|
|
17573
|
-
: // Cast because `ReadonlyArray` goes into the above but `isArray`
|
|
17574
|
-
// narrows to `Array`.
|
|
17575
|
-
propertiesFactory(/** @type {Props} */ (test))
|
|
17583
|
+
return Array.isArray(test) ? anyFactory(test) : propsFactory(test)
|
|
17576
17584
|
}
|
|
17577
17585
|
|
|
17578
17586
|
if (typeof test === 'string') {
|
|
@@ -17619,7 +17627,7 @@ function anyFactory(tests) {
|
|
|
17619
17627
|
* @param {Props} check
|
|
17620
17628
|
* @returns {Check}
|
|
17621
17629
|
*/
|
|
17622
|
-
function
|
|
17630
|
+
function propsFactory(check) {
|
|
17623
17631
|
const checkAsRecord = /** @type {Record<string, unknown>} */ (check);
|
|
17624
17632
|
|
|
17625
17633
|
return castFactory(all)
|
|
@@ -17708,7 +17716,8 @@ function color(d) {
|
|
|
17708
17716
|
}
|
|
17709
17717
|
|
|
17710
17718
|
/**
|
|
17711
|
-
* @
|
|
17719
|
+
* @typedef {import('unist').Node} UnistNode
|
|
17720
|
+
* @typedef {import('unist').Parent} UnistParent
|
|
17712
17721
|
*/
|
|
17713
17722
|
|
|
17714
17723
|
|
|
@@ -17811,9 +17820,9 @@ function visitParents(tree, test, visitor, reverse) {
|
|
|
17811
17820
|
typeof value.tagName === 'string'
|
|
17812
17821
|
? value.tagName
|
|
17813
17822
|
: // `xast`
|
|
17814
|
-
|
|
17815
|
-
|
|
17816
|
-
|
|
17823
|
+
typeof value.name === 'string'
|
|
17824
|
+
? value.name
|
|
17825
|
+
: undefined;
|
|
17817
17826
|
|
|
17818
17827
|
Object.defineProperty(visit, 'name', {
|
|
17819
17828
|
value:
|
|
@@ -21433,7 +21442,7 @@ const TypingIndicator = () => {
|
|
|
21433
21442
|
return (jsxRuntime.jsx("div", { className: "ai-chat-message assistant", children: jsxRuntime.jsxs("div", { className: "ai-chat-typing", children: [jsxRuntime.jsx("span", { className: "ai-chat-typing-dot" }), jsxRuntime.jsx("span", { className: "ai-chat-typing-dot" }), jsxRuntime.jsx("span", { className: "ai-chat-typing-dot" })] }) }));
|
|
21434
21443
|
};
|
|
21435
21444
|
|
|
21436
|
-
const MessageList = ({ messages, isTyping = false, showTypingIndicator = true, showTimestamps = true, enableFeedback = true, showSources = true, sourceDisplayMode = 'with-score', welcomeMessage, onFeedback, }) => {
|
|
21445
|
+
const MessageList = ({ messages, isTyping = false, showTypingIndicator = true, showTimestamps = true, enableFeedback = true, showSources = true, sourceDisplayMode = 'with-score', welcomeTitle, welcomeMessage, onFeedback, }) => {
|
|
21437
21446
|
const messagesEndRef = react.useRef(null);
|
|
21438
21447
|
// Auto-scroll to bottom when new messages arrive
|
|
21439
21448
|
react.useEffect(() => {
|
|
@@ -21453,7 +21462,7 @@ const MessageList = ({ messages, isTyping = false, showTypingIndicator = true, s
|
|
|
21453
21462
|
}
|
|
21454
21463
|
return map;
|
|
21455
21464
|
}, [messages]);
|
|
21456
|
-
return (jsxRuntime.jsxs("div", { className: "ai-chat-messages", role: "log", "aria-live": "polite", "aria-atomic": "false", children: [messages.length === 0 && welcomeMessage && (jsxRuntime.jsxs("div", { className: "ai-chat-welcome", children: [jsxRuntime.jsx("div", { className: "ai-chat-welcome-title", children:
|
|
21465
|
+
return (jsxRuntime.jsxs("div", { className: "ai-chat-messages", role: "log", "aria-live": "polite", "aria-atomic": "false", children: [messages.length === 0 && (welcomeTitle || welcomeMessage) && (jsxRuntime.jsxs("div", { className: "ai-chat-welcome", children: [welcomeTitle && (jsxRuntime.jsx("div", { className: "ai-chat-welcome-title", children: welcomeTitle })), welcomeMessage && (jsxRuntime.jsx("div", { className: "ai-chat-welcome-text", children: welcomeMessage }))] })), messages.map((message) => (jsxRuntime.jsx(Message, { message: message, showTimestamp: showTimestamps, enableFeedback: enableFeedback, showSources: showSources, sourceDisplayMode: sourceDisplayMode, toolCallNameById: toolCallNameById, onFeedback: onFeedback }, message.id))), isTyping && showTypingIndicator && jsxRuntime.jsx(TypingIndicator, {}), jsxRuntime.jsx("div", { ref: messagesEndRef })] }));
|
|
21457
21466
|
};
|
|
21458
21467
|
|
|
21459
21468
|
// Allowed file types
|
|
@@ -21479,7 +21488,7 @@ const formatFileSize = (bytes) => {
|
|
|
21479
21488
|
return (bytes / 1024).toFixed(1) + ' KB';
|
|
21480
21489
|
return (bytes / (1024 * 1024)).toFixed(1) + ' MB';
|
|
21481
21490
|
};
|
|
21482
|
-
const MessageInput = ({ onSend, placeholder = 'Type your message...', disabled = false, enableFileUpload = false, }) => {
|
|
21491
|
+
const MessageInput = ({ onSend, placeholder = 'Type your message...', disabled = false, enableFileUpload = false, separateFromChat = true, }) => {
|
|
21483
21492
|
const [value, setValue] = react.useState('');
|
|
21484
21493
|
const [selectedFiles, setSelectedFiles] = react.useState([]);
|
|
21485
21494
|
const textareaRef = react.useRef(null);
|
|
@@ -21537,7 +21546,8 @@ const MessageInput = ({ onSend, placeholder = 'Type your message...', disabled =
|
|
|
21537
21546
|
textareaRef.current.style.height = `${textareaRef.current.scrollHeight}px`;
|
|
21538
21547
|
}
|
|
21539
21548
|
};
|
|
21540
|
-
|
|
21549
|
+
console.log('[MessageInput] separateFromChat:', separateFromChat, 'class:', separateFromChat ? 'separate' : 'integrated');
|
|
21550
|
+
return (jsxRuntime.jsxs("div", { className: `ai-chat-input-container ${separateFromChat ? 'separate' : 'integrated'}`, children: [selectedFiles.length > 0 && (jsxRuntime.jsx("div", { className: "ai-chat-file-list", children: selectedFiles.map((file, index) => {
|
|
21541
21551
|
const ext = getFileExtension(file.name);
|
|
21542
21552
|
return (jsxRuntime.jsxs("div", { className: "ai-chat-file-item", children: [jsxRuntime.jsx("span", { className: "ai-chat-file-extension", children: ext }), jsxRuntime.jsxs("div", { className: "ai-chat-file-info", children: [jsxRuntime.jsx("span", { className: "ai-chat-file-name", children: file.name }), jsxRuntime.jsx("span", { className: "ai-chat-file-size", children: formatFileSize(file.size) })] }), jsxRuntime.jsx("button", { className: "ai-chat-file-remove", onClick: () => handleRemoveFile(index), "aria-label": "Remove file", children: "\u00D7" })] }, index));
|
|
21543
21553
|
}) })), jsxRuntime.jsxs("div", { className: "ai-chat-input-wrapper", children: [enableFileUpload && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("input", { ref: fileInputRef, type: "file", onChange: handleFileSelect, style: { display: 'none' }, multiple: true, accept: ALLOWED_EXTENSIONS.join(','), "aria-label": "File input" }), jsxRuntime.jsx("button", { className: "ai-chat-file-button", onClick: () => fileInputRef.current?.click(), disabled: disabled, "aria-label": "Attach file", children: jsxRuntime.jsx("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: jsxRuntime.jsx("path", { d: "M21.44 11.05l-9.19 9.19a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48" }) }) })] })), jsxRuntime.jsx("textarea", { ref: textareaRef, className: "ai-chat-input", value: value, onChange: handleChange, onKeyDown: handleKeyDown, placeholder: placeholder, disabled: disabled, rows: 1, "aria-label": "Message input" }), jsxRuntime.jsx("button", { className: "ai-chat-send-button", onClick: handleSend, disabled: disabled || (!value.trim() && selectedFiles.length === 0), "aria-label": "Send message", children: jsxRuntime.jsxs("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntime.jsx("line", { x1: "22", y1: "2", x2: "11", y2: "13" }), jsxRuntime.jsx("polygon", { points: "22 2 15 22 11 13 2 9 22 2" })] }) })] })] }));
|
|
@@ -21556,9 +21566,23 @@ const SuggestedQuestions = ({ questions, onQuestionClick, }) => {
|
|
|
21556
21566
|
};
|
|
21557
21567
|
|
|
21558
21568
|
const ChatWindow = ({ messages, isLoading, isTyping, error, config, onSendMessage, onClose, onFeedback, }) => {
|
|
21569
|
+
console.log('[ChatWindow] Rendering ChatWindow component');
|
|
21559
21570
|
const appearance = config?.appearance;
|
|
21560
21571
|
const behavior = config?.behavior;
|
|
21561
21572
|
const size = appearance?.size || 'medium';
|
|
21573
|
+
console.log('[ChatWindow] Size:', size, 'Appearance:', !!appearance);
|
|
21574
|
+
// Determine current theme config
|
|
21575
|
+
const themePreference = appearance?.theme ?? 'light';
|
|
21576
|
+
const canUseDarkMode = appearance?.darkModeEnabled !== false;
|
|
21577
|
+
const prefersDark = typeof window !== 'undefined' && window.matchMedia('(prefers-color-scheme: dark)').matches;
|
|
21578
|
+
const isDarkMode = themePreference === 'auto'
|
|
21579
|
+
? (canUseDarkMode && prefersDark)
|
|
21580
|
+
: themePreference === 'dark' && canUseDarkMode;
|
|
21581
|
+
const themeConfig = (isDarkMode ? appearance?.darkMode : appearance?.lightMode) ?? (appearance?.lightMode || appearance?.darkMode);
|
|
21582
|
+
const headerTitle = themeConfig?.header?.title ?? appearance?.header?.title ?? appearance?.companyName ?? 'AI Assistant';
|
|
21583
|
+
const welcomeTitle = themeConfig?.chat?.welcomeTitle ?? 'Welcome!';
|
|
21584
|
+
const welcomeMessage = themeConfig?.chat?.welcomeMessage ?? appearance?.welcomeMessage ?? '👋 Hi there! How can I assist you today?';
|
|
21585
|
+
const inputPlaceholder = themeConfig?.footer?.inputPlaceholder ?? appearance?.placeholder ?? 'Ask me anything...';
|
|
21562
21586
|
// Track if suggested questions should be shown
|
|
21563
21587
|
const [showSuggestedQuestions, setShowSuggestedQuestions] = react.useState(true);
|
|
21564
21588
|
// Hide suggested questions after first user message
|
|
@@ -21577,9 +21601,244 @@ const ChatWindow = ({ messages, isLoading, isTyping, error, config, onSendMessag
|
|
|
21577
21601
|
setShowSuggestedQuestions(false);
|
|
21578
21602
|
onSendMessage(question);
|
|
21579
21603
|
};
|
|
21580
|
-
return (jsxRuntime.jsxs("div", { className: `ai-chat-window size-${size}`, role: "dialog", "aria-label": "Chat window", children: [jsxRuntime.jsxs("div", { className: "ai-chat-header", children: [jsxRuntime.jsxs("div", { className: "ai-chat-header-content", children: [appearance?.logo && (jsxRuntime.jsx("img", { src: appearance.logo, alt: "Logo", className: "ai-chat-logo" })), jsxRuntime.jsx("div", { className: "ai-chat-title", children:
|
|
21604
|
+
return (jsxRuntime.jsxs("div", { className: `ai-chat-window size-${size}`, role: "dialog", "aria-label": "Chat window", children: [jsxRuntime.jsxs("div", { className: "ai-chat-header", children: [jsxRuntime.jsxs("div", { className: "ai-chat-header-content", children: [appearance?.logo && (jsxRuntime.jsx("img", { src: appearance.logo, alt: "Logo", className: "ai-chat-logo" })), jsxRuntime.jsx("div", { className: "ai-chat-title", children: headerTitle })] }), jsxRuntime.jsx("button", { className: "ai-chat-close-button", onClick: onClose, "aria-label": "Close chat", children: jsxRuntime.jsxs("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntime.jsx("line", { x1: "18", y1: "6", x2: "6", y2: "18" }), jsxRuntime.jsx("line", { x1: "6", y1: "6", x2: "18", y2: "18" })] }) })] }), error && (jsxRuntime.jsx("div", { className: "ai-chat-error", role: "alert", children: error })), maxMessages && userMessageCount >= maxMessages - 2 && !isLimitReached && (jsxRuntime.jsxs("div", { className: "ai-chat-warning", role: "alert", children: [maxMessages - userMessageCount, " message", maxMessages - userMessageCount !== 1 ? 's' : '', " remaining in this session"] })), isLimitReached && (jsxRuntime.jsxs("div", { className: "ai-chat-error", role: "alert", children: ["Message limit reached (", maxMessages, " messages per session). Please start a new conversation."] })), jsxRuntime.jsx(MessageList, { messages: messages, isTyping: isTyping, showTypingIndicator: behavior?.showTypingIndicator, showTimestamps: behavior?.showTimestamps, enableFeedback: behavior?.enableFeedback, showSources: behavior?.showSources, sourceDisplayMode: behavior?.sourceDisplayMode, welcomeTitle: welcomeTitle, welcomeMessage: welcomeMessage, onFeedback: onFeedback }), showSuggestedQuestions && behavior?.suggestedQuestions && behavior.suggestedQuestions.length > 0 && (jsxRuntime.jsx(SuggestedQuestions, { questions: behavior.suggestedQuestions, onQuestionClick: handleQuestionClick })), jsxRuntime.jsx(MessageInput, { onSend: onSendMessage, placeholder: isLimitReached ? 'Message limit reached' : inputPlaceholder, disabled: isLoading || isLimitReached, enableFileUpload: behavior?.enableFileUpload, separateFromChat: themeConfig?.footer?.separateFromChat })] }));
|
|
21581
21605
|
};
|
|
21582
21606
|
|
|
21607
|
+
/**
|
|
21608
|
+
* Convert shadow size to CSS box-shadow value
|
|
21609
|
+
*/
|
|
21610
|
+
function getShadowValue(size) {
|
|
21611
|
+
const shadows = {
|
|
21612
|
+
'none': 'none',
|
|
21613
|
+
'sm': '0 1px 2px 0 rgba(0, 0, 0, 0.05)',
|
|
21614
|
+
'md': '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)',
|
|
21615
|
+
'lg': '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)',
|
|
21616
|
+
'xl': '0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)',
|
|
21617
|
+
'2xl': '0 25px 50px -12px rgba(0, 0, 0, 0.25)',
|
|
21618
|
+
};
|
|
21619
|
+
return shadows[size] || shadows.none;
|
|
21620
|
+
}
|
|
21621
|
+
/**
|
|
21622
|
+
* Apply appearance configuration as CSS custom properties
|
|
21623
|
+
* This allows the widget to be fully customizable via the appearance config
|
|
21624
|
+
*
|
|
21625
|
+
* @param appearance - Widget appearance configuration
|
|
21626
|
+
* @param theme - Current theme ('light' or 'dark')
|
|
21627
|
+
*/
|
|
21628
|
+
function applyAppearanceStyles(appearance, theme = 'light') {
|
|
21629
|
+
const styles = {};
|
|
21630
|
+
// Global font family
|
|
21631
|
+
if (appearance.fontFamily) {
|
|
21632
|
+
styles.fontFamily = appearance.fontFamily;
|
|
21633
|
+
}
|
|
21634
|
+
// Select the correct theme configuration
|
|
21635
|
+
const themeConfig = theme === 'dark' ? appearance.darkMode : appearance.lightMode;
|
|
21636
|
+
// If theme config exists and has required properties, use it
|
|
21637
|
+
if (themeConfig && themeConfig.button) {
|
|
21638
|
+
// ========================================================================
|
|
21639
|
+
// BUTTON APPEARANCE
|
|
21640
|
+
// ========================================================================
|
|
21641
|
+
const btn = themeConfig.button;
|
|
21642
|
+
if (btn.color)
|
|
21643
|
+
styles['--button-color'] = btn.color;
|
|
21644
|
+
if (btn.opacity !== undefined)
|
|
21645
|
+
styles['--button-opacity'] = btn.opacity.toString();
|
|
21646
|
+
if (btn.size)
|
|
21647
|
+
styles['--button-size'] = `${btn.size}px`;
|
|
21648
|
+
if (btn.icon)
|
|
21649
|
+
styles['--button-icon'] = btn.icon;
|
|
21650
|
+
if (btn.iconColor)
|
|
21651
|
+
styles['--button-icon-color'] = btn.iconColor;
|
|
21652
|
+
if (btn.borderRadius !== undefined)
|
|
21653
|
+
styles['--button-border-radius'] = `${btn.borderRadius}px`;
|
|
21654
|
+
if (btn.borderWidth !== undefined)
|
|
21655
|
+
styles['--button-border-width'] = `${btn.borderWidth}px`;
|
|
21656
|
+
if (btn.borderColor)
|
|
21657
|
+
styles['--button-border-color'] = btn.borderColor;
|
|
21658
|
+
if (btn.borderOpacity !== undefined)
|
|
21659
|
+
styles['--button-border-opacity'] = btn.borderOpacity.toString();
|
|
21660
|
+
if (btn.backdropBlur !== undefined)
|
|
21661
|
+
styles['--button-backdrop-blur'] = `${btn.backdropBlur}px`;
|
|
21662
|
+
if (btn.shadow)
|
|
21663
|
+
styles['--button-shadow'] = getShadowValue(btn.shadow);
|
|
21664
|
+
// ========================================================================
|
|
21665
|
+
// CARD/WINDOW APPEARANCE
|
|
21666
|
+
// ========================================================================
|
|
21667
|
+
const card = themeConfig.card;
|
|
21668
|
+
if (card.backgroundColor)
|
|
21669
|
+
styles['--card-background'] = card.backgroundColor;
|
|
21670
|
+
if (card.opacity !== undefined)
|
|
21671
|
+
styles['--card-opacity'] = card.opacity.toString();
|
|
21672
|
+
if (card.borderRadius !== undefined)
|
|
21673
|
+
styles['--card-border-radius'] = `${card.borderRadius}px`;
|
|
21674
|
+
if (card.borderWidth !== undefined)
|
|
21675
|
+
styles['--card-border-width'] = `${card.borderWidth}px`;
|
|
21676
|
+
if (card.borderColor) {
|
|
21677
|
+
styles['--card-border-color'] = card.borderColor;
|
|
21678
|
+
// Create rgba border color with opacity for box-shadow
|
|
21679
|
+
if (card.borderOpacity !== undefined) {
|
|
21680
|
+
const opacity = card.borderOpacity;
|
|
21681
|
+
// Convert hex to rgba
|
|
21682
|
+
const hex = card.borderColor.replace('#', '');
|
|
21683
|
+
const r = parseInt(hex.substring(0, 2), 16);
|
|
21684
|
+
const g = parseInt(hex.substring(2, 4), 16);
|
|
21685
|
+
const b = parseInt(hex.substring(4, 6), 16);
|
|
21686
|
+
styles['--card-border-color-rgba'] = `rgba(${r}, ${g}, ${b}, ${opacity})`;
|
|
21687
|
+
}
|
|
21688
|
+
}
|
|
21689
|
+
if (card.borderOpacity !== undefined)
|
|
21690
|
+
styles['--card-border-opacity'] = card.borderOpacity.toString();
|
|
21691
|
+
if (card.backdropBlur !== undefined)
|
|
21692
|
+
styles['--card-backdrop-blur'] = `${card.backdropBlur}px`;
|
|
21693
|
+
if (card.shadow)
|
|
21694
|
+
styles['--card-shadow'] = getShadowValue(card.shadow);
|
|
21695
|
+
// ========================================================================
|
|
21696
|
+
// HEADER APPEARANCE
|
|
21697
|
+
// ========================================================================
|
|
21698
|
+
const header = themeConfig.header;
|
|
21699
|
+
if (header.backgroundColor)
|
|
21700
|
+
styles['--header-background'] = header.backgroundColor;
|
|
21701
|
+
if (header.opacity !== undefined)
|
|
21702
|
+
styles['--header-opacity'] = header.opacity.toString();
|
|
21703
|
+
if (header.textColor)
|
|
21704
|
+
styles['--header-text-color'] = header.textColor;
|
|
21705
|
+
if (header.borderBottomWidth !== undefined)
|
|
21706
|
+
styles['--header-border-bottom-width'] = `${header.borderBottomWidth}px`;
|
|
21707
|
+
if (header.borderBottomColor)
|
|
21708
|
+
styles['--header-border-bottom-color'] = header.borderBottomColor;
|
|
21709
|
+
if (header.borderBottomOpacity !== undefined)
|
|
21710
|
+
styles['--header-border-bottom-opacity'] = header.borderBottomOpacity.toString();
|
|
21711
|
+
// ========================================================================
|
|
21712
|
+
// CHAT APPEARANCE
|
|
21713
|
+
// ========================================================================
|
|
21714
|
+
const chat = themeConfig.chat;
|
|
21715
|
+
if (chat.backgroundColor)
|
|
21716
|
+
styles['--chat-background'] = chat.backgroundColor;
|
|
21717
|
+
if (chat.opacity !== undefined)
|
|
21718
|
+
styles['--chat-opacity'] = chat.opacity.toString();
|
|
21719
|
+
// Welcome message
|
|
21720
|
+
if (chat.welcomeColor)
|
|
21721
|
+
styles['--welcome-color'] = chat.welcomeColor;
|
|
21722
|
+
// Message bubbles
|
|
21723
|
+
if (chat.enableBubbles) {
|
|
21724
|
+
if (chat.bubbleUserColor)
|
|
21725
|
+
styles['--bubble-user-color'] = chat.bubbleUserColor;
|
|
21726
|
+
if (chat.bubbleUserOpacity !== undefined)
|
|
21727
|
+
styles['--bubble-user-opacity'] = chat.bubbleUserOpacity.toString();
|
|
21728
|
+
if (chat.bubbleAssistantColor)
|
|
21729
|
+
styles['--bubble-assistant-color'] = chat.bubbleAssistantColor;
|
|
21730
|
+
if (chat.bubbleAssistantOpacity !== undefined)
|
|
21731
|
+
styles['--bubble-assistant-opacity'] = chat.bubbleAssistantOpacity.toString();
|
|
21732
|
+
if (chat.bubbleBorderWidth !== undefined)
|
|
21733
|
+
styles['--bubble-border-width'] = `${chat.bubbleBorderWidth}px`;
|
|
21734
|
+
if (chat.bubbleBorderColor)
|
|
21735
|
+
styles['--bubble-border-color'] = chat.bubbleBorderColor;
|
|
21736
|
+
if (chat.bubbleBorderOpacity !== undefined)
|
|
21737
|
+
styles['--bubble-border-opacity'] = chat.bubbleBorderOpacity.toString();
|
|
21738
|
+
}
|
|
21739
|
+
else {
|
|
21740
|
+
// Plain text mode
|
|
21741
|
+
if (chat.textColor)
|
|
21742
|
+
styles['--message-text-color'] = chat.textColor;
|
|
21743
|
+
}
|
|
21744
|
+
// ========================================================================
|
|
21745
|
+
// FOOTER APPEARANCE
|
|
21746
|
+
// ========================================================================
|
|
21747
|
+
const footer = themeConfig.footer;
|
|
21748
|
+
// Only if separate from chat
|
|
21749
|
+
if (footer.separateFromChat) {
|
|
21750
|
+
if (footer.backgroundColor)
|
|
21751
|
+
styles['--footer-background'] = footer.backgroundColor;
|
|
21752
|
+
if (footer.opacity !== undefined)
|
|
21753
|
+
styles['--footer-opacity'] = footer.opacity.toString();
|
|
21754
|
+
if (footer.borderTopWidth !== undefined)
|
|
21755
|
+
styles['--footer-border-top-width'] = `${footer.borderTopWidth}px`;
|
|
21756
|
+
if (footer.borderTopColor)
|
|
21757
|
+
styles['--footer-border-top-color'] = footer.borderTopColor;
|
|
21758
|
+
if (footer.borderTopOpacity !== undefined)
|
|
21759
|
+
styles['--footer-border-top-opacity'] = footer.borderTopOpacity.toString();
|
|
21760
|
+
}
|
|
21761
|
+
// Backdrop blur (only when floating)
|
|
21762
|
+
if (!footer.separateFromChat && footer.backdropBlur !== undefined) {
|
|
21763
|
+
styles['--footer-backdrop-blur'] = `${footer.backdropBlur}px`;
|
|
21764
|
+
}
|
|
21765
|
+
// Input field
|
|
21766
|
+
if (footer.inputBackgroundColor)
|
|
21767
|
+
styles['--input-background'] = footer.inputBackgroundColor;
|
|
21768
|
+
if (footer.inputBackgroundOpacity !== undefined)
|
|
21769
|
+
styles['--input-background-opacity'] = footer.inputBackgroundOpacity.toString();
|
|
21770
|
+
if (footer.inputBorderRadius !== undefined)
|
|
21771
|
+
styles['--input-border-radius'] = `${footer.inputBorderRadius}px`;
|
|
21772
|
+
if (footer.inputBorderWidth !== undefined)
|
|
21773
|
+
styles['--input-border-width'] = `${footer.inputBorderWidth}px`;
|
|
21774
|
+
if (footer.inputBorderColor)
|
|
21775
|
+
styles['--input-border-color'] = footer.inputBorderColor;
|
|
21776
|
+
if (footer.inputBorderOpacity !== undefined)
|
|
21777
|
+
styles['--input-border-opacity'] = footer.inputBorderOpacity.toString();
|
|
21778
|
+
if (footer.inputShadow)
|
|
21779
|
+
styles['--input-shadow'] = getShadowValue(footer.inputShadow);
|
|
21780
|
+
// Send button
|
|
21781
|
+
if (footer.buttonBackgroundColor)
|
|
21782
|
+
styles['--send-button-background'] = footer.buttonBackgroundColor;
|
|
21783
|
+
if (footer.buttonOpacity !== undefined)
|
|
21784
|
+
styles['--send-button-opacity'] = footer.buttonOpacity.toString();
|
|
21785
|
+
if (footer.buttonBorderRadius !== undefined)
|
|
21786
|
+
styles['--send-button-border-radius'] = `${footer.buttonBorderRadius}px`;
|
|
21787
|
+
if (footer.buttonBorderWidth !== undefined)
|
|
21788
|
+
styles['--send-button-border-width'] = `${footer.buttonBorderWidth}px`;
|
|
21789
|
+
if (footer.buttonBorderColor)
|
|
21790
|
+
styles['--send-button-border-color'] = footer.buttonBorderColor;
|
|
21791
|
+
if (footer.buttonBorderOpacity !== undefined)
|
|
21792
|
+
styles['--send-button-border-opacity'] = footer.buttonBorderOpacity.toString();
|
|
21793
|
+
// ========================================================================
|
|
21794
|
+
// HOVER STATES
|
|
21795
|
+
// ========================================================================
|
|
21796
|
+
const hover = themeConfig.hover;
|
|
21797
|
+
if (hover.buttonScale !== undefined)
|
|
21798
|
+
styles['--hover-button-scale'] = hover.buttonScale.toString();
|
|
21799
|
+
if (hover.buttonOpacity !== undefined)
|
|
21800
|
+
styles['--hover-button-opacity'] = hover.buttonOpacity.toString();
|
|
21801
|
+
if (hover.inputBorderColor)
|
|
21802
|
+
styles['--hover-input-border-color'] = hover.inputBorderColor;
|
|
21803
|
+
if (hover.sendButtonOpacity !== undefined)
|
|
21804
|
+
styles['--hover-send-button-opacity'] = hover.sendButtonOpacity.toString();
|
|
21805
|
+
if (hover.closeButtonOpacity !== undefined)
|
|
21806
|
+
styles['--hover-close-button-opacity'] = hover.closeButtonOpacity.toString();
|
|
21807
|
+
// ========================================================================
|
|
21808
|
+
// ACTIVE STATES
|
|
21809
|
+
// ========================================================================
|
|
21810
|
+
const active = themeConfig.active;
|
|
21811
|
+
if (active.inputBorderColor)
|
|
21812
|
+
styles['--active-input-border-color'] = active.inputBorderColor;
|
|
21813
|
+
if (active.inputShadow)
|
|
21814
|
+
styles['--active-input-shadow'] = active.inputShadow;
|
|
21815
|
+
}
|
|
21816
|
+
else {
|
|
21817
|
+
// Fallback to legacy fields if no theme config
|
|
21818
|
+
if (appearance.primaryColor)
|
|
21819
|
+
styles['--primary-color'] = appearance.primaryColor;
|
|
21820
|
+
if (appearance.borderRadius !== undefined)
|
|
21821
|
+
styles['--border-radius'] = `${appearance.borderRadius}px`;
|
|
21822
|
+
// Legacy button
|
|
21823
|
+
if (appearance.button) {
|
|
21824
|
+
const btn = appearance.button;
|
|
21825
|
+
if (btn.color)
|
|
21826
|
+
styles['--button-color'] = btn.color;
|
|
21827
|
+
if (btn.size)
|
|
21828
|
+
styles['--button-size'] = `${btn.size}px`;
|
|
21829
|
+
if (btn.borderRadius !== undefined)
|
|
21830
|
+
styles['--button-border-radius'] = `${btn.borderRadius}px`;
|
|
21831
|
+
if (btn.borderWidth !== undefined)
|
|
21832
|
+
styles['--button-border-width'] = `${btn.borderWidth}px`;
|
|
21833
|
+
if (btn.borderColor)
|
|
21834
|
+
styles['--button-border-color'] = btn.borderColor;
|
|
21835
|
+
if (btn.opacity !== undefined)
|
|
21836
|
+
styles['--button-opacity'] = btn.opacity.toString();
|
|
21837
|
+
}
|
|
21838
|
+
}
|
|
21839
|
+
return styles;
|
|
21840
|
+
}
|
|
21841
|
+
|
|
21583
21842
|
function styleInject(css, ref) {
|
|
21584
21843
|
if ( ref === void 0 ) ref = {};
|
|
21585
21844
|
var insertAt = ref.insertAt;
|
|
@@ -21607,11 +21866,26 @@ function styleInject(css, ref) {
|
|
|
21607
21866
|
}
|
|
21608
21867
|
}
|
|
21609
21868
|
|
|
21610
|
-
var css_248z = ".ai-chat-widget{--primary-color:#7c3aed;--background-color:#fff;--text-color:#1f2937;--border-color:#e5e7eb;--user-message-bg:var(--primary-color);--user-message-text:#fff;--assistant-message-bg:#f3f4f6;--assistant-message-text:#1f2937;--input-bg:#fff;--input-border:#d1d5db;--shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -1px rgba(0,0,0,.06);--shadow-lg:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -2px rgba(0,0,0,.05);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif}.ai-chat-widget.dark{--background-color:#1f2937;--text-color:#f9fafb;--border-color:#374151;--assistant-message-bg:#374151;--assistant-message-text:#f9fafb;--input-bg:#374151;--input-border:#4b5563}.ai-chat-widget.dark .ai-chat-message.system .ai-chat-message-content{background-color:#78350f;color:#fef3c7}.ai-chat-widget.dark .ai-chat-message.tool .ai-chat-message-content{background-color:#1e3a8a;color:#dbeafe}.ai-chat-widget-container{font-size:14px;line-height:1.5;position:fixed;z-index:9999}.ai-chat-widget-container.bottom-right{bottom:20px;right:20px}.ai-chat-widget-container.bottom-left{bottom:20px;left:20px}.ai-chat-widget-container.top-right{right:20px;top:20px}.ai-chat-widget-container.top-left{left:20px;top:20px}.ai-chat-button{align-items:center;background-color:var(--primary-color);border:none;border-radius:50%;box-shadow:var(--shadow-lg);color:#fff;cursor:pointer;display:flex;font-size:24px;height:60px;justify-content:center;transition:transform .2s,box-shadow .2s;width:60px}.ai-chat-button:hover{box-shadow:0 20px 25px -5px rgba(0,0,0,.1),0 10px 10px -5px rgba(0,0,0,.04);transform:scale(1.05)}.ai-chat-button:active{transform:scale(.95)}.ai-chat-button-svg{height:50%;min-height:24px;min-width:24px;width:50%}.ai-chat-button-icon{font-size:1.5em;line-height:1}.ai-chat-window{background-color:var(--background-color);border-radius:12px;box-shadow:var(--shadow-lg);display:flex;flex-direction:column;overflow:hidden;transition:opacity .2s,transform .2s}.ai-chat-window.size-small{height:400px;width:300px}.ai-chat-window.size-medium{height:600px;width:400px}.ai-chat-window.size-large{height:700px;width:500px}.ai-chat-header{align-items:center;background-color:var(--primary-color);color:#fff;display:flex;justify-content:space-between;padding:16px}.ai-chat-header-content{align-items:center;display:flex;flex:1;gap:12px}.ai-chat-logo{border-radius:50%;height:32px;object-fit:cover;width:32px}.ai-chat-title{font-size:16px;font-weight:600}.ai-chat-close-button{align-items:center;background:none;border:none;border-radius:4px;color:#fff;cursor:pointer;display:flex;justify-content:center;padding:4px;transition:background-color .2s}.ai-chat-close-button:hover{background-color:hsla(0,0%,100%,.1)}.ai-chat-messages{background-color:var(--background-color);display:flex;flex:1;flex-direction:column;gap:12px;overflow-y:auto;padding:16px}.ai-chat-messages::-webkit-scrollbar{width:6px}.ai-chat-messages::-webkit-scrollbar-track{background:transparent}.ai-chat-messages::-webkit-scrollbar-thumb{background:var(--border-color);border-radius:3px}.ai-chat-messages::-webkit-scrollbar-thumb:hover{background:var(--input-border)}.ai-chat-message{animation:slideIn .2s ease-out;display:flex;flex-direction:column;gap:4px}@keyframes slideIn{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}.ai-chat-message.user{align-items:flex-end}.ai-chat-message.assistant{align-items:flex-start}.ai-chat-message.system{align-items:center}.ai-chat-message.tool{align-items:flex-start}.ai-chat-message-content{word-wrap:break-word;border-radius:12px;line-height:1.5;max-width:80%;padding:10px 14px}.ai-chat-message.user .ai-chat-message-content{background-color:var(--user-message-bg);border-bottom-right-radius:4px;color:var(--user-message-text)}.ai-chat-message.assistant .ai-chat-message-content{background-color:var(--assistant-message-bg);border-bottom-left-radius:4px;color:var(--assistant-message-text)}.ai-chat-message.system .ai-chat-message-content{background-color:#fef3c7;border-radius:8px;color:#92400e;font-size:12px;font-style:italic;max-width:90%;text-align:center}.ai-chat-message.tool .ai-chat-message-content{background-color:#dbeafe;border-bottom-left-radius:4px;color:#1e40af;font-family:Courier New,monospace;font-size:13px}.ai-chat-tool-indicators{display:flex;gap:6px;margin-top:6px}.tool-indicator{align-items:center;background:#dbeafe;border-radius:50%;color:#1e40af;display:inline-flex;height:18px;justify-content:center;overflow:hidden;position:relative;width:18px}.tool-indicator .icon{font-size:12px;line-height:1;z-index:1}.tool-indicator.started:after{animation:ai-spin 1s linear infinite;border:2px solid rgba(30,64,175,.25);border-radius:50%;border-top-color:#1e40af;content:\"\";inset:0;position:absolute}@keyframes ai-spin{to{transform:rotate(1turn)}}.ai-chat-tool-message{background:linear-gradient(135deg,#ecfdf5,#d1fae5);border:1px solid #a7f3d0;border-radius:9999px;box-shadow:0 1px 2px rgba(0,0,0,.04),0 1px 8px rgba(16,185,129,.08);color:#065f46;gap:10px;padding:6px 12px}.ai-chat-tool-message,.tool-finished{align-items:center;display:inline-flex}.tool-finished{background:rgba(16,185,129,.12);border-radius:50%;color:#059669;height:22px;justify-content:center;position:relative;width:22px}.tool-finished .tool-icon{font-size:14px}.tool-finished .tool-check{align-items:center;background:#10b981;border-radius:50%;bottom:-3px;box-shadow:0 1px 2px rgba(0,0,0,.12);color:#fff;display:inline-flex;font-size:10px;height:14px;justify-content:center;position:absolute;right:-3px;width:14px}.tool-name{font-size:12px;font-weight:600}.ai-chat-message-timestamp{color:#9ca3af;font-size:11px;padding:0 4px}.ai-chat-welcome{color:var(--text-color);padding:32px 16px;text-align:center}.ai-chat-welcome-title{font-size:18px;font-weight:600;margin-bottom:8px}.ai-chat-welcome-text{color:#6b7280;font-size:14px}.ai-chat-typing{align-items:center;background-color:var(--assistant-message-bg);border-radius:12px;border-bottom-left-radius:4px;display:flex;gap:4px;max-width:80px;padding:10px 14px}.ai-chat-typing-dot{animation:typingBounce 1.4s infinite;background-color:#9ca3af;border-radius:50%;height:8px;width:8px}.ai-chat-typing-dot:nth-child(2){animation-delay:.2s}.ai-chat-typing-dot:nth-child(3){animation-delay:.4s}@keyframes typingBounce{0%,60%,to{transform:translateY(0)}30%{transform:translateY(-8px)}}.ai-chat-input-container{background-color:var(--background-color);border-top:1px solid var(--border-color);padding:16px}.ai-chat-input-wrapper{align-items:flex-end;display:flex;gap:8px}.ai-chat-input{background-color:var(--input-bg);border:1px solid var(--input-border);border-radius:8px;color:var(--text-color);flex:1;font-family:inherit;font-size:14px;max-height:120px;min-height:40px;outline:none;padding:10px 12px;resize:none;transition:border-color .2s}.ai-chat-input:focus{border-color:var(--primary-color)}.ai-chat-input::placeholder{color:#9ca3af}.ai-chat-send-button{align-items:center;background-color:var(--primary-color);border:none;border-radius:8px;color:#fff;cursor:pointer;display:flex;font-weight:500;height:40px;justify-content:center;min-width:40px;padding:10px 16px;transition:opacity .2s,transform .1s}.ai-chat-send-button:hover:not(:disabled){opacity:.9}.ai-chat-send-button:active:not(:disabled){transform:scale(.95)}.ai-chat-send-button:disabled{cursor:not-allowed;opacity:.5}.ai-chat-file-button{align-items:center;background:none;border:none;border-radius:6px;color:var(--text-color);cursor:pointer;display:flex;justify-content:center;padding:8px;transition:background-color .2s}.ai-chat-file-button:hover:not(:disabled){background-color:rgba(0,0,0,.05)}.ai-chat-file-button:disabled{cursor:not-allowed;opacity:.5}.ai-chat-file-list{display:flex;flex-wrap:wrap;gap:8px;padding:8px 12px}.ai-chat-file-item{align-items:center;background-color:rgba(0,0,0,.05);border-radius:6px;display:flex;font-size:12px;gap:8px;padding:6px 10px}.ai-chat-file-extension{background-color:var(--primary-color);border-radius:3px;color:#fff;display:inline-block;font-size:10px;font-weight:600;min-width:40px;padding:2px 6px;text-align:center;text-transform:uppercase}.ai-chat-file-info{display:flex;flex:1;flex-direction:column;gap:2px;min-width:0}.ai-chat-file-name{font-weight:500;max-width:150px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ai-chat-file-size{color:var(--text-muted);font-size:10px;opacity:.7}.ai-chat-file-remove{background:none;border:none;cursor:pointer;font-size:18px;line-height:1;opacity:.6;padding:0 4px;transition:opacity .2s}.ai-chat-file-remove:hover{opacity:1}.ai-chat-message-attachments{display:flex;flex-wrap:wrap;gap:6px;margin-top:6px}.ai-chat-message-attachment{align-items:center;background-color:rgba(0,0,0,.08);border-radius:4px;display:inline-flex;font-size:11px;gap:4px;padding:3px 8px}.ai-chat-attachment-icon{font-size:12px}.ai-chat-attachment-ext{background-color:var(--primary-color);border-radius:2px;color:#fff;display:inline-block;font-size:9px;font-weight:600;padding:1px 4px;text-transform:uppercase}.ai-chat-attachment-name{max-width:120px;opacity:.8;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ai-chat-sources{background-color:rgba(0,0,0,.02);border-radius:6px;font-size:12px;margin-top:8px;overflow:hidden}.ai-chat-sources-toggle{align-items:center;background:none;border:none;cursor:pointer;display:flex;gap:6px;padding:8px 10px;text-align:left;transition:background-color .2s;width:100%}.ai-chat-sources-toggle:hover{background-color:rgba(0,0,0,.03)}.ai-chat-sources-icon{color:var(--text-muted);font-size:10px;transition:transform .2s}.ai-chat-sources-title{color:var(--text-color);flex:1;font-size:11px;font-weight:600;letter-spacing:.5px;text-transform:uppercase}.ai-chat-source-item{border-top:1px solid rgba(0,0,0,.05);color:#6b7280;display:flex;gap:8px;padding:8px 10px}.ai-chat-source-item:last-child{border-bottom:none}.ai-chat-source-number{color:var(--primary-color);flex-shrink:0;font-weight:600}.ai-chat-source-details{display:flex;flex:1;flex-direction:column;gap:4px}.ai-chat-source-score{color:#9ca3af;font-size:11px}.ai-chat-source-content{color:#6b7280;font-size:11px;font-style:italic;line-height:1.4}.ai-chat-source-metadata{display:flex;flex-wrap:wrap;gap:6px;margin-top:2px}.ai-chat-source-meta-item{background-color:rgba(0,0,0,.05);border-radius:3px;color:#6b7280;font-size:10px;padding:2px 6px}.ai-chat-feedback{align-items:center;display:flex;gap:8px;margin-top:8px;min-height:32px}.ai-chat-feedback-button{align-items:center;background:none;border:none;border-radius:6px;cursor:pointer;display:flex;font-size:16px;gap:4px;overflow:hidden;padding:6px 10px;position:relative;transition:all .2s ease}.ai-chat-feedback-button:hover:not(:disabled){background-color:rgba(0,0,0,.05);transform:scale(1.2)}.ai-chat-feedback-button:active:not(:disabled){transform:scale(.95)}.ai-chat-feedback-button:disabled{cursor:not-allowed;opacity:.5}.ai-chat-feedback-button.active{background-color:rgba(124,58,237,.1)}.ai-chat-feedback-submitted{align-items:center;animation:feedbackMorph .3s cubic-bezier(.34,1.56,.64,1);display:flex;gap:6px}.ai-chat-feedback-checkmark{animation:checkmarkPop .3s cubic-bezier(.34,1.56,.64,1);color:#10b981;font-size:16px;font-weight:700}.ai-chat-feedback-text{animation:textSlideIn .3s ease;color:#10b981;font-size:13px;font-weight:500}@keyframes feedbackMorph{0%{opacity:.5;transform:scale(.8)}to{opacity:1;transform:scale(1)}}@keyframes checkmarkPop{0%{opacity:0;transform:scale(0) rotate(-45deg)}50%{transform:scale(1.3) rotate(0deg)}to{opacity:1;transform:scale(1) rotate(0deg)}}@keyframes textSlideIn{0%{opacity:0;transform:translateX(-10px)}to{opacity:1;transform:translateX(0)}}.ai-chat-error{align-items:flex-start;background-color:#fee2e2;border-left:4px solid #dc2626;border-radius:8px;color:#991b1b;display:flex;font-size:14px;font-weight:500;gap:8px;line-height:1.5;margin:8px 16px;padding:12px 16px}.ai-chat-error:before{content:\"⚠️\";flex-shrink:0;font-size:16px}.ai-chat-warning{background-color:#fef3c7;border-radius:8px;color:#92400e;font-size:13px;margin:8px 16px;padding:12px}.ai-chat-suggested-questions{margin-bottom:8px;padding:12px 16px}.ai-chat-suggested-questions-label{color:#6b7280;font-size:12px;font-weight:500;margin-bottom:8px}.ai-chat-suggested-questions-list{display:flex;flex-direction:column;gap:8px}.ai-chat-suggested-question{align-items:center;background-color:#f9fafb;border:1px solid #e5e7eb;border-radius:8px;color:#374151;cursor:pointer;display:flex;font-size:14px;gap:8px;padding:10px 12px;text-align:left;transition:all .2s ease;width:100%}.ai-chat-suggested-question:hover{background-color:#f3f4f6;border-color:var(--ai-chat-primary-color,#6366f1);box-shadow:0 2px 4px rgba(0,0,0,.05);transform:translateY(-1px)}.ai-chat-suggested-question:active{transform:translateY(0)}.ai-chat-suggested-question-icon{flex-shrink:0;font-size:16px}.ai-chat-suggested-question-text{flex:1;line-height:1.4}@media (max-width:480px){.ai-chat-window{border-radius:0!important;bottom:0!important;height:100%!important;left:0!important;position:fixed!important;right:0!important;top:0!important;width:100%!important}.ai-chat-widget-container{bottom:20px!important;right:20px!important}.ai-chat-suggested-question{font-size:13px;padding:9px 10px}}.ai-chat-action-approval{background:linear-gradient(135deg,#667eea,#764ba2);border-radius:12px;box-shadow:0 4px 12px rgba(102,126,234,.3);color:#fff;margin:16px;padding:16px}.ai-chat-action-approval-content{align-items:flex-start;display:flex;gap:12px;margin-bottom:16px}.ai-chat-action-approval-icon{align-items:center;background:hsla(0,0%,100%,.2);border-radius:8px;display:flex;flex-shrink:0;height:40px;justify-content:center;width:40px}.ai-chat-action-approval-text{flex:1}.ai-chat-action-approval-title{font-size:15px;font-weight:600;margin-bottom:4px}.ai-chat-action-approval-description{font-size:13px;line-height:1.4;opacity:.95}.ai-chat-action-approval-buttons{display:flex;gap:8px;justify-content:flex-end}.ai-chat-action-button{align-items:center;border:none;border-radius:8px;cursor:pointer;display:flex;font-family:inherit;font-size:14px;font-weight:500;gap:6px;padding:8px 16px;transition:all .2s ease}.ai-chat-action-button:disabled{cursor:not-allowed;opacity:.6}.ai-chat-action-button-reject{background:hsla(0,0%,100%,.2);color:#fff}.ai-chat-action-button-reject:hover:not(:disabled){background:hsla(0,0%,100%,.3)}.ai-chat-action-button-approve{background:#fff;color:#667eea}.ai-chat-action-button-approve:hover:not(:disabled){background:#f0f0f0;box-shadow:0 2px 8px rgba(0,0,0,.15);transform:translateY(-1px)}.ai-chat-action-spinner{animation:ai-chat-spin .6s linear infinite;border:2px solid rgba(102,126,234,.3);border-radius:50%;border-top-color:#667eea;display:inline-block;height:14px;width:14px}@keyframes ai-chat-spin{to{transform:rotate(1turn)}}";
|
|
21869
|
+
var css_248z = ".ai-chat-widget{--primary-color:#07f;--background-color:#fff;--text-color:#1f2937;--border-color:#e5e7eb;--user-message-bg:var(--primary-color);--user-message-text:#fff;--assistant-message-bg:#f3f4f6;--assistant-message-text:#374151;--input-bg:#fff;--input-border:#d1d5db;--shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -1px rgba(0,0,0,.06);--shadow-lg:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -2px rgba(0,0,0,.05);--button-color:#07f;--button-size:56px;--button-border-radius:28px;--button-border-width:0px;--button-border-color:#07f;--button-opacity:1;--button-backdrop-blur:0px;--button-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -2px rgba(0,0,0,.05);--card-background:#fff;--card-border-radius:16px;--card-border-width:0px;--card-border-color:#e5e7eb;--card-opacity:1;--card-backdrop-blur:0px;--card-shadow:0 25px 50px -12px rgba(0,0,0,.25);--header-background:#07f;--header-text-color:#fff;--header-font-size:18px;--header-border-bottom-width:0px;--header-border-bottom-color:#e5e7eb;--header-opacity:1;--header-backdrop-blur:0px;--chat-background:#fff;--chat-opacity:1;--chat-backdrop-blur:0px;--welcome-font-size:16px;--welcome-color:#1f2937;--welcome-opacity:1;--bubble-user-color:#07f;--bubble-assistant-color:#f3f4f6;--bubble-border-radius:16px;--bubble-border-width:0px;--bubble-border-color:#e5e7eb;--bubble-opacity:1;--typing-animation-color:#f3f4f6;--typing-animation-opacity:1;--typing-animation-border-width:0px;--typing-animation-border-color:#e5e7eb;--typing-animation-border-radius:16px;--footer-background:#fff;--footer-border-top-width:1px;--footer-border-top-color:#e5e7eb;--footer-opacity:1;--footer-backdrop-blur:0px;--input-background:#fff;--input-border-radius:24px;--input-border-width:1.5px;--input-border-color:#d1d5db;--input-opacity:1;--input-shadow:0 1px 2px 0 rgba(0,0,0,.05);--send-button-background:#07f;--send-button-border-radius:20px;--send-button-border-width:0px;--send-button-border-color:#07f;--send-button-opacity:1;--hover-button-scale:1.05;--hover-button-opacity:0.9;--hover-input-border-color:#9ca3af;--hover-send-button-opacity:0.85;--hover-close-button-opacity:1;--active-input-border-color:#07f;--active-input-shadow:0 0 0 3px rgba(0,119,255,.1);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif}.ai-chat-widget.dark{--background-color:#001d3d;--text-color:#f9fafb;--border-color:#374151;--assistant-message-bg:#036;--assistant-message-text:#e5e7eb;--input-bg:#002855;--input-border:#374151}.ai-chat-widget.dark .ai-chat-message.system .ai-chat-message-content{background-color:#78350f;color:#fef3c7}.ai-chat-widget.dark .ai-chat-message.tool .ai-chat-message-content{background-color:#1e3a8a;color:#dbeafe}.ai-chat-widget-container{font-size:14px;line-height:1.5;position:fixed;z-index:9999}.ai-chat-widget-container.bottom-right{bottom:20px;right:20px}.ai-chat-widget-container.bottom-left{bottom:20px;left:20px}.ai-chat-widget-container.top-right{right:20px;top:20px}.ai-chat-widget-container.top-left{left:20px;top:20px}.ai-chat-button{align-items:center;backdrop-filter:blur(var(--button-backdrop-blur));-webkit-backdrop-filter:blur(var(--button-backdrop-blur));background-color:var(--button-color);border:var(--button-border-width) solid var(--button-border-color);border-radius:var(--button-border-radius);box-shadow:var(--button-shadow);color:#fff;cursor:pointer;display:flex;height:var(--button-size);justify-content:center;opacity:var(--button-opacity);transition:all .3s cubic-bezier(.4,0,.2,1);width:var(--button-size)}.ai-chat-button:hover{box-shadow:0 20px 25px -5px rgba(0,0,0,.1),0 10px 10px -5px rgba(0,0,0,.04);opacity:var(--hover-button-opacity);transform:scale(var(--hover-button-scale))}.ai-chat-button:active{transform:scale(.95)}.ai-chat-button-svg{height:50%;min-height:24px;min-width:24px;width:50%}.ai-chat-button-icon{font-size:1.5em;line-height:1}.ai-chat-window{border-radius:var(--card-border-radius);box-shadow:0 0 0 var(--card-border-width) var(--card-border-color-rgba,var(--card-border-color)),var(--card-shadow);display:flex;flex-direction:column;overflow:hidden;position:absolute}.ai-chat-window>*{position:relative;z-index:1}.ai-chat-window:before{backdrop-filter:blur(var(--card-backdrop-blur));-webkit-backdrop-filter:blur(var(--card-backdrop-blur));background-color:var(--card-background);border-radius:var(--card-border-radius);content:\"\";inset:0;opacity:var(--card-opacity);pointer-events:none;position:absolute;z-index:0}.ai-chat-widget-container.bottom-right .ai-chat-window{bottom:0;right:0}.ai-chat-widget-container.bottom-left .ai-chat-window{bottom:0;left:0}.ai-chat-widget-container.top-right .ai-chat-window{right:0;top:0}.ai-chat-widget-container.top-left .ai-chat-window{left:0;top:0}.ai-chat-window.size-small{height:500px;width:380px}.ai-chat-window.size-medium{height:650px;width:440px}.ai-chat-window.size-large{height:750px;width:520px}.ai-chat-header{align-items:center;border-bottom:var(--header-border-bottom-width) solid var(--header-border-bottom-color);box-shadow:0 2px 8px rgba(0,0,0,.1);color:var(--header-text-color);display:flex;justify-content:space-between;padding:20px;position:relative}.ai-chat-header:before{backdrop-filter:blur(var(--header-backdrop-blur));-webkit-backdrop-filter:blur(var(--header-backdrop-blur));background-color:var(--header-background);content:\"\";inset:0;opacity:var(--header-opacity);pointer-events:none;position:absolute;z-index:0}.ai-chat-header>*{position:relative;z-index:1}.ai-chat-header-content{align-items:center;display:flex;flex:1;gap:12px}.ai-chat-logo{border-radius:50%;height:32px;object-fit:cover;width:32px}.ai-chat-title{color:var(--header-text-color);font-size:var(--header-font-size);font-weight:600;letter-spacing:-.01em}.ai-chat-close-button{align-items:center;background:none;border:none;border-radius:8px;color:var(--header-text-color);cursor:pointer;display:flex;justify-content:center;opacity:.9;padding:8px;transition:all .2s ease}.ai-chat-close-button:hover{background-color:hsla(0,0%,100%,.15);opacity:var(--hover-close-button-opacity);transform:scale(1.05)}.ai-chat-messages{background-color:var(--chat-background);display:flex;flex:1;flex-direction:column;gap:16px;overflow-x:hidden;overflow-y:auto;padding:20px;position:relative}.ai-chat-window:has(.ai-chat-input-container.integrated) .ai-chat-messages{padding-bottom:100px}.ai-chat-messages:before{backdrop-filter:blur(var(--chat-backdrop-blur));-webkit-backdrop-filter:blur(var(--chat-backdrop-blur));background-color:var(--chat-background);bottom:0;content:\"\";left:0;opacity:var(--chat-opacity);pointer-events:none;position:absolute;right:0;top:0;z-index:0}.ai-chat-messages>*{position:relative;z-index:1}.ai-chat-messages::-webkit-scrollbar{width:6px}.ai-chat-messages::-webkit-scrollbar-track{background:transparent}.ai-chat-messages::-webkit-scrollbar-thumb{background:var(--border-color);border-radius:3px}.ai-chat-messages::-webkit-scrollbar-thumb:hover{background:var(--input-border)}.ai-chat-message{animation:slideIn .2s ease-out;display:flex;flex-direction:column;gap:4px}@keyframes slideIn{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}.ai-chat-message.user{align-items:flex-end}.ai-chat-message.assistant{align-items:flex-start}.ai-chat-message.system{align-items:center}.ai-chat-message.tool{align-items:flex-start}.ai-chat-message-content{word-wrap:break-word;border:var(--bubble-border-width) solid var(--bubble-border-color);border-radius:var(--bubble-border-radius);font-size:15px;line-height:1.6;max-width:80%;opacity:var(--bubble-opacity);padding:12px 16px}.ai-chat-message.user .ai-chat-message-content{background-color:var(--bubble-user-color);border-bottom-right-radius:4px;box-shadow:0 1px 2px rgba(0,0,0,.1);color:var(--user-message-text)}.ai-chat-message.assistant .ai-chat-message-content{background-color:var(--bubble-assistant-color);border-bottom-left-radius:4px;box-shadow:0 1px 2px rgba(0,0,0,.05);color:var(--assistant-message-text)}.ai-chat-message.system .ai-chat-message-content{background-color:#fef3c7;border-radius:8px;color:#92400e;font-size:12px;font-style:italic;max-width:90%;text-align:center}.ai-chat-message.tool .ai-chat-message-content{background-color:#dbeafe;border-bottom-left-radius:4px;color:#1e40af;font-family:Courier New,monospace;font-size:13px}.ai-chat-tool-indicators{display:flex;gap:6px;margin-top:6px}.tool-indicator{align-items:center;background:#dbeafe;border-radius:50%;color:#1e40af;display:inline-flex;height:18px;justify-content:center;overflow:hidden;position:relative;width:18px}.tool-indicator .icon{font-size:12px;line-height:1;z-index:1}.tool-indicator.started:after{animation:ai-spin 1s linear infinite;border:2px solid rgba(30,64,175,.25);border-radius:50%;border-top-color:#1e40af;content:\"\";inset:0;position:absolute}@keyframes ai-spin{to{transform:rotate(1turn)}}.ai-chat-tool-message{background:linear-gradient(135deg,#ecfdf5,#d1fae5);border:1px solid #a7f3d0;border-radius:9999px;box-shadow:0 1px 2px rgba(0,0,0,.04),0 1px 8px rgba(16,185,129,.08);color:#065f46;gap:10px;padding:6px 12px}.ai-chat-tool-message,.tool-finished{align-items:center;display:inline-flex}.tool-finished{background:rgba(16,185,129,.12);border-radius:50%;color:#059669;height:22px;justify-content:center;position:relative;width:22px}.tool-finished .tool-icon{font-size:14px}.tool-finished .tool-check{align-items:center;background:#10b981;border-radius:50%;bottom:-3px;box-shadow:0 1px 2px rgba(0,0,0,.12);color:#fff;display:inline-flex;font-size:10px;height:14px;justify-content:center;position:absolute;right:-3px;width:14px}.tool-name{font-size:12px;font-weight:600}.ai-chat-message-timestamp{color:rgba(0,0,0,.6);filter:invert(1) grayscale(1) contrast(1.2);font-size:11px;mix-blend-mode:difference;padding:0 4px}.ai-chat-welcome{color:var(--welcome-color);opacity:var(--welcome-opacity);padding:48px 24px;text-align:center}.ai-chat-welcome-title{color:var(--welcome-color);font-size:calc(var(--welcome-font-size)*1.5);font-weight:700;letter-spacing:-.02em;margin-bottom:12px}.ai-chat-welcome-text{color:var(--welcome-color);font-size:var(--welcome-font-size);line-height:1.6}.ai-chat-typing{align-items:center;background-color:var(--assistant-message-bg);border-radius:12px;border-bottom-left-radius:4px;display:flex;gap:4px;max-width:80px;padding:10px 14px}.ai-chat-typing-dot{animation:typingBounce 1.4s infinite;background-color:#9ca3af;border-radius:50%;height:8px;width:8px}.ai-chat-typing-dot:nth-child(2){animation-delay:.2s}.ai-chat-typing-dot:nth-child(3){animation-delay:.4s}@keyframes typingBounce{0%,60%,to{transform:translateY(0)}30%{transform:translateY(-8px)}}.ai-chat-input-container{padding:20px;position:relative}.ai-chat-input-container.separate{border-top:var(--footer-border-top-width) solid var(--footer-border-top-color)}.ai-chat-input-container.integrated{bottom:0;left:0;padding-bottom:calc(20px + var(--card-border-width));position:absolute;right:0;z-index:10}.ai-chat-input-container.separate:before{backdrop-filter:blur(var(--footer-backdrop-blur));-webkit-backdrop-filter:blur(var(--footer-backdrop-blur));background-color:var(--footer-background);content:\"\";inset:0;opacity:var(--footer-opacity);pointer-events:none;position:absolute;z-index:0}.ai-chat-input-container>*{position:relative;z-index:1}.ai-chat-input-wrapper{align-items:center;background-color:var(--input-background);border:var(--input-border-width) solid var(--input-border-color);border-radius:var(--input-border-radius);display:flex;gap:0;opacity:var(--input-opacity);padding:6px 6px 6px 16px;transition:all .2s ease}.ai-chat-input-wrapper:hover{border-color:var(--hover-input-border-color)}.ai-chat-input-wrapper:focus-within{border-color:var(--active-input-border-color);box-shadow:var(--active-input-shadow)}.ai-chat-input{background-color:transparent;border:none;border-radius:0;color:var(--text-color);flex:1;font-family:inherit;font-size:15px;max-height:120px;min-height:40px;outline:none;padding:10px 0;resize:none}.ai-chat-input::placeholder{color:#9ca3af}.ai-chat-send-button{align-items:center;background-color:var(--send-button-background);border:var(--send-button-border-width) solid var(--send-button-border-color);border-radius:var(--send-button-border-radius);color:#fff;cursor:pointer;display:flex;flex-shrink:0;font-weight:500;height:40px;justify-content:center;min-width:40px;opacity:var(--send-button-opacity);padding:0;transition:all .2s ease;width:40px}.ai-chat-send-button:hover:not(:disabled){opacity:var(--hover-send-button-opacity);transform:scale(1.05)}.ai-chat-send-button:active:not(:disabled){transform:scale(.98)}.ai-chat-send-button:disabled{cursor:not-allowed;opacity:.5}.ai-chat-file-button{align-items:center;background:none;border:none;border-radius:6px;color:var(--text-color);cursor:pointer;display:flex;justify-content:center;padding:8px;transition:background-color .2s}.ai-chat-file-button:hover:not(:disabled){background-color:rgba(0,0,0,.05)}.ai-chat-file-button:disabled{cursor:not-allowed;opacity:.5}.ai-chat-file-list{display:flex;flex-wrap:wrap;gap:8px;padding:8px 12px}.ai-chat-file-item{align-items:center;background-color:rgba(0,0,0,.05);border-radius:6px;display:flex;font-size:12px;gap:8px;padding:6px 10px}.ai-chat-file-extension{background-color:var(--primary-color);border-radius:3px;color:#fff;display:inline-block;font-size:10px;font-weight:600;min-width:40px;padding:2px 6px;text-align:center;text-transform:uppercase}.ai-chat-file-info{display:flex;flex:1;flex-direction:column;gap:2px;min-width:0}.ai-chat-file-name{font-weight:500;max-width:150px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ai-chat-file-size{color:var(--text-muted);font-size:10px;opacity:.7}.ai-chat-file-remove{background:none;border:none;cursor:pointer;font-size:18px;line-height:1;opacity:.6;padding:0 4px;transition:opacity .2s}.ai-chat-file-remove:hover{opacity:1}.ai-chat-message-attachments{display:flex;flex-wrap:wrap;gap:6px;margin-top:6px}.ai-chat-message-attachment{align-items:center;background-color:rgba(0,0,0,.08);border-radius:4px;display:inline-flex;font-size:11px;gap:4px;padding:3px 8px}.ai-chat-attachment-icon{font-size:12px}.ai-chat-attachment-ext{background-color:var(--primary-color);border-radius:2px;color:#fff;display:inline-block;font-size:9px;font-weight:600;padding:1px 4px;text-transform:uppercase}.ai-chat-attachment-name{max-width:120px;opacity:.8;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ai-chat-sources{background-color:rgba(0,0,0,.02);border-radius:6px;font-size:12px;margin-top:8px;overflow:hidden}.ai-chat-sources-toggle{align-items:center;background:none;border:none;cursor:pointer;display:flex;gap:6px;padding:8px 10px;text-align:left;transition:background-color .2s;width:100%}.ai-chat-sources-toggle:hover{background-color:rgba(0,0,0,.03)}.ai-chat-sources-icon{color:var(--text-muted);font-size:10px;transition:transform .2s}.ai-chat-sources-title{color:var(--text-color);flex:1;font-size:11px;font-weight:600;letter-spacing:.5px;text-transform:uppercase}.ai-chat-source-item{border-top:1px solid rgba(0,0,0,.05);color:#6b7280;display:flex;gap:8px;padding:8px 10px}.ai-chat-source-item:last-child{border-bottom:none}.ai-chat-source-number{color:var(--primary-color);flex-shrink:0;font-weight:600}.ai-chat-source-details{display:flex;flex:1;flex-direction:column;gap:4px}.ai-chat-source-score{color:#9ca3af;font-size:11px}.ai-chat-source-content{color:#6b7280;font-size:11px;font-style:italic;line-height:1.4}.ai-chat-source-metadata{display:flex;flex-wrap:wrap;gap:6px;margin-top:2px}.ai-chat-source-meta-item{background-color:rgba(0,0,0,.05);border-radius:3px;color:#6b7280;font-size:10px;padding:2px 6px}.ai-chat-feedback{align-items:center;display:flex;gap:8px;margin-top:8px;min-height:32px}.ai-chat-feedback-button{align-items:center;background:none;border:none;border-radius:6px;cursor:pointer;display:flex;filter:drop-shadow(0 1px 2px rgba(0,0,0,.3));font-size:16px;gap:4px;overflow:hidden;padding:6px 10px;position:relative;transition:all .2s ease}.ai-chat-feedback-button:hover:not(:disabled){background-color:rgba(0,0,0,.05);transform:scale(1.2)}.ai-chat-feedback-button:active:not(:disabled){transform:scale(.95)}.ai-chat-feedback-button:disabled{cursor:not-allowed;opacity:.5}.ai-chat-feedback-button.active{background-color:rgba(0,119,255,.1)}.ai-chat-feedback-submitted{align-items:center;animation:feedbackMorph .3s cubic-bezier(.34,1.56,.64,1);display:flex;gap:6px}.ai-chat-feedback-checkmark{animation:checkmarkPop .3s cubic-bezier(.34,1.56,.64,1);color:#10b981;font-size:16px;font-weight:700}.ai-chat-feedback-text{animation:textSlideIn .3s ease;color:#10b981;font-size:13px;font-weight:500}@keyframes feedbackMorph{0%{opacity:.5;transform:scale(.8)}to{opacity:1;transform:scale(1)}}@keyframes checkmarkPop{0%{opacity:0;transform:scale(0) rotate(-45deg)}50%{transform:scale(1.3) rotate(0deg)}to{opacity:1;transform:scale(1) rotate(0deg)}}@keyframes textSlideIn{0%{opacity:0;transform:translateX(-10px)}to{opacity:1;transform:translateX(0)}}.ai-chat-error{align-items:flex-start;background-color:#fee2e2;border-left:4px solid #dc2626;border-radius:8px;color:#991b1b;display:flex;font-size:14px;font-weight:500;gap:8px;line-height:1.5;margin:8px 16px;padding:12px 16px}.ai-chat-error:before{content:\"⚠️\";flex-shrink:0;font-size:16px}.ai-chat-warning{background-color:#fef3c7;border-radius:8px;color:#92400e;font-size:13px;margin:8px 16px;padding:12px}.ai-chat-suggested-questions{margin-bottom:8px;padding:12px 16px}.ai-chat-suggested-questions-label{color:#6b7280;font-size:12px;font-weight:500;margin-bottom:8px}.ai-chat-suggested-questions-list{display:flex;flex-direction:column;gap:8px}.ai-chat-suggested-question{align-items:center;background-color:#f9fafb;border:1px solid #e5e7eb;border-radius:8px;color:#374151;cursor:pointer;display:flex;font-size:14px;gap:8px;padding:10px 12px;text-align:left;transition:all .2s ease;width:100%}.ai-chat-suggested-question:hover{background-color:#f3f4f6;border-color:var(--ai-chat-primary-color,#6366f1);box-shadow:0 2px 4px rgba(0,0,0,.05);transform:translateY(-1px)}.ai-chat-suggested-question:active{transform:translateY(0)}.ai-chat-suggested-question-icon{flex-shrink:0;font-size:16px}.ai-chat-suggested-question-text{flex:1;line-height:1.4}@media (max-width:480px){.ai-chat-window{border-radius:0!important;bottom:0!important;height:100%!important;left:0!important;position:fixed!important;right:0!important;top:0!important;width:100%!important}.ai-chat-widget-container{bottom:20px!important;right:20px!important}.ai-chat-suggested-question{font-size:13px;padding:9px 10px}}.ai-chat-action-approval{background:linear-gradient(135deg,#07f,#001d3d);border-radius:16px;box-shadow:0 4px 12px rgba(0,119,255,.3);color:#fff;margin:16px;padding:16px}.ai-chat-action-approval-content{align-items:flex-start;display:flex;gap:12px;margin-bottom:16px}.ai-chat-action-approval-icon{align-items:center;background:hsla(0,0%,100%,.2);border-radius:8px;display:flex;flex-shrink:0;height:40px;justify-content:center;width:40px}.ai-chat-action-approval-text{flex:1}.ai-chat-action-approval-title{font-size:15px;font-weight:600;margin-bottom:4px}.ai-chat-action-approval-description{font-size:13px;line-height:1.4;opacity:.95}.ai-chat-action-approval-buttons{display:flex;gap:8px;justify-content:flex-end}.ai-chat-action-button{align-items:center;border:none;border-radius:8px;cursor:pointer;display:flex;font-family:inherit;font-size:14px;font-weight:500;gap:6px;padding:8px 16px;transition:all .2s ease}.ai-chat-action-button:disabled{cursor:not-allowed;opacity:.6}.ai-chat-action-button-reject{background:hsla(0,0%,100%,.2);color:#fff}.ai-chat-action-button-reject:hover:not(:disabled){background:hsla(0,0%,100%,.3)}.ai-chat-action-button-approve{background:#fff;color:#07f}.ai-chat-action-button-approve:hover:not(:disabled){background:#f0f0f0;box-shadow:0 2px 8px rgba(0,0,0,.15);transform:translateY(-1px)}.ai-chat-action-spinner{animation:ai-chat-spin .6s linear infinite;border:2px solid rgba(0,119,255,.3);border-radius:50%;border-top-color:#07f;display:inline-block;height:14px;width:14px}@keyframes ai-chat-spin{to{transform:rotate(1turn)}}";
|
|
21611
21870
|
styleInject(css_248z);
|
|
21612
21871
|
|
|
21872
|
+
// Icon components mapping
|
|
21873
|
+
const iconComponents = {
|
|
21874
|
+
FiMessageCircle: () => (jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: jsxRuntime.jsx("path", { d: "M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z" }) })),
|
|
21875
|
+
FiMessageSquare: () => (jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: jsxRuntime.jsx("path", { d: "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" }) })),
|
|
21876
|
+
FiMail: () => (jsxRuntime.jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntime.jsx("path", { d: "M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z" }), jsxRuntime.jsx("polyline", { points: "22,6 12,13 2,6" })] })),
|
|
21877
|
+
FiPhone: () => (jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: jsxRuntime.jsx("path", { d: "M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z" }) })),
|
|
21878
|
+
FiHelpCircle: () => (jsxRuntime.jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntime.jsx("circle", { cx: "12", cy: "12", r: "10" }), jsxRuntime.jsx("path", { d: "M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3" }), jsxRuntime.jsx("line", { x1: "12", y1: "17", x2: "12.01", y2: "17" })] })),
|
|
21879
|
+
FiZap: () => (jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: jsxRuntime.jsx("polygon", { points: "13 2 3 14 12 14 11 22 21 10 12 10 13 2" }) })),
|
|
21880
|
+
FiSend: () => (jsxRuntime.jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntime.jsx("line", { x1: "22", y1: "2", x2: "11", y2: "13" }), jsxRuntime.jsx("polygon", { points: "22 2 15 22 11 13 2 9 22 2" })] })),
|
|
21881
|
+
FiUser: () => (jsxRuntime.jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntime.jsx("path", { d: "M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2" }), jsxRuntime.jsx("circle", { cx: "12", cy: "7", r: "4" })] })),
|
|
21882
|
+
FiUsers: () => (jsxRuntime.jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntime.jsx("path", { d: "M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2" }), jsxRuntime.jsx("circle", { cx: "9", cy: "7", r: "4" }), jsxRuntime.jsx("path", { d: "M23 21v-2a4 4 0 0 0-3-3.87" }), jsxRuntime.jsx("path", { d: "M16 3.13a4 4 0 0 1 0 7.75" })] })),
|
|
21883
|
+
FiHeadphones: () => (jsxRuntime.jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntime.jsx("path", { d: "M3 18v-6a9 9 0 0 1 18 0v6" }), jsxRuntime.jsx("path", { d: "M21 19a2 2 0 0 1-2 2h-1a2 2 0 0 1-2-2v-3a2 2 0 0 1 2-2h3zM3 19a2 2 0 0 0 2 2h1a2 2 0 0 0 2-2v-3a2 2 0 0 0-2-2H3z" })] })),
|
|
21884
|
+
FiCpu: () => (jsxRuntime.jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntime.jsx("rect", { x: "4", y: "4", width: "16", height: "16", rx: "2", ry: "2" }), jsxRuntime.jsx("rect", { x: "9", y: "9", width: "6", height: "6" }), jsxRuntime.jsx("line", { x1: "9", y1: "1", x2: "9", y2: "4" }), jsxRuntime.jsx("line", { x1: "15", y1: "1", x2: "15", y2: "4" }), jsxRuntime.jsx("line", { x1: "9", y1: "20", x2: "9", y2: "23" }), jsxRuntime.jsx("line", { x1: "15", y1: "20", x2: "15", y2: "23" }), jsxRuntime.jsx("line", { x1: "20", y1: "9", x2: "23", y2: "9" }), jsxRuntime.jsx("line", { x1: "20", y1: "14", x2: "23", y2: "14" }), jsxRuntime.jsx("line", { x1: "1", y1: "9", x2: "4", y2: "9" }), jsxRuntime.jsx("line", { x1: "1", y1: "14", x2: "4", y2: "14" })] })),
|
|
21885
|
+
};
|
|
21613
21886
|
const ChatWidget = ({ widgetId, apiKey, apiUrl = window.location.origin, position = 'bottom-right', theme: themeOverride, primaryColor, onOpen, onClose, onMessage, onError, }) => {
|
|
21614
21887
|
const [isOpen, setIsOpen] = react.useState(false);
|
|
21888
|
+
const widgetRef = react.useRef(null);
|
|
21615
21889
|
const { messages, isLoading, isTyping, error, config, sendMessage, submitFeedback, } = useChat({
|
|
21616
21890
|
widgetId,
|
|
21617
21891
|
apiKey,
|
|
@@ -21619,6 +21893,21 @@ const ChatWidget = ({ widgetId, apiKey, apiUrl = window.location.origin, positio
|
|
|
21619
21893
|
onMessage,
|
|
21620
21894
|
onError,
|
|
21621
21895
|
});
|
|
21896
|
+
// Debug logging
|
|
21897
|
+
react.useEffect(() => {
|
|
21898
|
+
console.log('[ChatWidget] Config loaded:', config ? 'YES' : 'NO');
|
|
21899
|
+
if (config) {
|
|
21900
|
+
console.log('[ChatWidget] Config details:', {
|
|
21901
|
+
theme: config.appearance?.theme,
|
|
21902
|
+
darkModeEnabled: config.appearance?.darkModeEnabled,
|
|
21903
|
+
hasLightMode: !!config.appearance?.lightMode,
|
|
21904
|
+
hasDarkMode: !!config.appearance?.darkMode,
|
|
21905
|
+
});
|
|
21906
|
+
}
|
|
21907
|
+
}, [config]);
|
|
21908
|
+
react.useEffect(() => {
|
|
21909
|
+
console.log('[ChatWidget] isOpen changed:', isOpen);
|
|
21910
|
+
}, [isOpen]);
|
|
21622
21911
|
// Handle auto-open
|
|
21623
21912
|
react.useEffect(() => {
|
|
21624
21913
|
if (config?.behavior.autoOpen) {
|
|
@@ -21631,26 +21920,84 @@ const ChatWidget = ({ widgetId, apiKey, apiUrl = window.location.origin, positio
|
|
|
21631
21920
|
}
|
|
21632
21921
|
return undefined;
|
|
21633
21922
|
}, [config, onOpen]);
|
|
21923
|
+
// Handle close on outside click
|
|
21924
|
+
react.useEffect(() => {
|
|
21925
|
+
if (!isOpen || !config?.appearance.closeOnOutsideClick)
|
|
21926
|
+
return;
|
|
21927
|
+
const handleClickOutside = (event) => {
|
|
21928
|
+
if (widgetRef.current && !widgetRef.current.contains(event.target)) {
|
|
21929
|
+
console.log('[ChatWidget] Closing due to outside click');
|
|
21930
|
+
setIsOpen(false);
|
|
21931
|
+
onClose?.();
|
|
21932
|
+
}
|
|
21933
|
+
};
|
|
21934
|
+
// Add slight delay to avoid immediate close on open
|
|
21935
|
+
const timer = setTimeout(() => {
|
|
21936
|
+
document.addEventListener('mousedown', handleClickOutside);
|
|
21937
|
+
}, 100);
|
|
21938
|
+
return () => {
|
|
21939
|
+
clearTimeout(timer);
|
|
21940
|
+
document.removeEventListener('mousedown', handleClickOutside);
|
|
21941
|
+
};
|
|
21942
|
+
}, [isOpen, config, onClose]);
|
|
21943
|
+
// Handle close on Escape key
|
|
21944
|
+
react.useEffect(() => {
|
|
21945
|
+
if (!isOpen || !config?.appearance.closeOnEscape)
|
|
21946
|
+
return;
|
|
21947
|
+
const handleEscapeKey = (event) => {
|
|
21948
|
+
if (event.key === 'Escape') {
|
|
21949
|
+
setIsOpen(false);
|
|
21950
|
+
onClose?.();
|
|
21951
|
+
}
|
|
21952
|
+
};
|
|
21953
|
+
document.addEventListener('keydown', handleEscapeKey);
|
|
21954
|
+
return () => document.removeEventListener('keydown', handleEscapeKey);
|
|
21955
|
+
}, [isOpen, config, onClose]);
|
|
21634
21956
|
// Determine theme
|
|
21635
|
-
const
|
|
21636
|
-
const
|
|
21637
|
-
|
|
21638
|
-
|
|
21957
|
+
const appearanceConfig = config?.appearance;
|
|
21958
|
+
const themeSetting = themeOverride || appearanceConfig?.theme || 'light';
|
|
21959
|
+
const canUseDarkMode = appearanceConfig?.darkModeEnabled !== false;
|
|
21960
|
+
// Only check system preference if dark mode is enabled
|
|
21961
|
+
const systemPrefersDark = canUseDarkMode && typeof window !== "undefined"
|
|
21962
|
+
? window.matchMedia('(prefers-color-scheme: dark)').matches
|
|
21963
|
+
: false;
|
|
21964
|
+
const effectiveTheme = !canUseDarkMode
|
|
21965
|
+
? 'light' // Force light mode if dark mode is disabled
|
|
21966
|
+
: themeSetting === 'auto'
|
|
21967
|
+
? (systemPrefersDark ? 'dark' : 'light')
|
|
21968
|
+
: themeSetting === 'dark'
|
|
21969
|
+
? 'dark'
|
|
21970
|
+
: 'light';
|
|
21639
21971
|
// Determine position (config takes priority over prop)
|
|
21640
21972
|
const effectivePosition = config?.appearance.position || position;
|
|
21641
|
-
// Apply custom styles
|
|
21642
|
-
|
|
21643
|
-
|
|
21644
|
-
|
|
21645
|
-
|
|
21646
|
-
if
|
|
21647
|
-
|
|
21648
|
-
|
|
21649
|
-
|
|
21650
|
-
|
|
21651
|
-
|
|
21973
|
+
// Apply custom styles from appearance configuration
|
|
21974
|
+
// Use the correct theme configuration (lightMode or darkMode)
|
|
21975
|
+
const customStyles = appearanceConfig
|
|
21976
|
+
? applyAppearanceStyles(appearanceConfig, effectiveTheme)
|
|
21977
|
+
: {};
|
|
21978
|
+
// Override with prop values if provided
|
|
21979
|
+
if (primaryColor) {
|
|
21980
|
+
customStyles['--primary-color'] = primaryColor;
|
|
21981
|
+
}
|
|
21982
|
+
// Debug logging for theme and styles
|
|
21983
|
+
react.useEffect(() => {
|
|
21984
|
+
console.log('[ChatWidget] Theme info:', {
|
|
21985
|
+
effectiveTheme,
|
|
21986
|
+
canUseDarkMode,
|
|
21987
|
+
themeSetting,
|
|
21988
|
+
systemPrefersDark,
|
|
21989
|
+
hasCustomStyles: Object.keys(customStyles).length > 0,
|
|
21990
|
+
buttonColor: customStyles['--button-color'],
|
|
21991
|
+
buttonSize: customStyles['--button-size'],
|
|
21992
|
+
cardBackground: customStyles['--card-background'],
|
|
21993
|
+
cardOpacity: customStyles['--card-opacity'],
|
|
21994
|
+
cardBorderRadius: customStyles['--card-border-radius'],
|
|
21995
|
+
});
|
|
21996
|
+
console.log('[ChatWidget] All CSS variables:', customStyles);
|
|
21997
|
+
}, [effectiveTheme, customStyles]);
|
|
21652
21998
|
const handleToggle = () => {
|
|
21653
21999
|
const newState = !isOpen;
|
|
22000
|
+
console.log('[ChatWidget] handleToggle called, setting isOpen to:', newState);
|
|
21654
22001
|
setIsOpen(newState);
|
|
21655
22002
|
if (newState) {
|
|
21656
22003
|
onOpen?.();
|
|
@@ -21662,10 +22009,22 @@ const ChatWidget = ({ widgetId, apiKey, apiUrl = window.location.origin, positio
|
|
|
21662
22009
|
const handleFeedback = async (messageId, feedback) => {
|
|
21663
22010
|
await submitFeedback(messageId, feedback);
|
|
21664
22011
|
};
|
|
21665
|
-
|
|
21666
|
-
|
|
21667
|
-
|
|
21668
|
-
|
|
22012
|
+
// Don't render until config is loaded to avoid flash of unstyled content
|
|
22013
|
+
if (!config) {
|
|
22014
|
+
console.log('[ChatWidget] Not rendering - config not loaded yet');
|
|
22015
|
+
return null;
|
|
22016
|
+
}
|
|
22017
|
+
console.log('[ChatWidget] Rendering widget', { isOpen, hasConfig: !!config });
|
|
22018
|
+
return (jsxRuntime.jsx("div", { className: `ai-chat-widget ${effectiveTheme}`, style: customStyles, children: jsxRuntime.jsxs("div", { ref: widgetRef, className: `ai-chat-widget-container ${effectivePosition}`, children: [isOpen && (jsxRuntime.jsx(ChatWindow, { messages: messages, isLoading: isLoading, isTyping: isTyping, error: error, config: config, onSendMessage: sendMessage, onClose: handleToggle, onFeedback: handleFeedback })), !isOpen && (() => {
|
|
22019
|
+
// Get icon from theme config
|
|
22020
|
+
const themeConfig = effectiveTheme === 'dark'
|
|
22021
|
+
? appearanceConfig?.darkMode
|
|
22022
|
+
: appearanceConfig?.lightMode;
|
|
22023
|
+
const buttonIcon = themeConfig?.button?.icon || 'FiMessageCircle';
|
|
22024
|
+
const buttonIconColor = themeConfig?.button?.iconColor || customStyles['--button-icon-color'] || '#ffffff';
|
|
22025
|
+
const IconComponent = iconComponents[buttonIcon] || iconComponents.FiMessageCircle;
|
|
22026
|
+
return (jsxRuntime.jsx("button", { className: "ai-chat-button", onClick: handleToggle, "aria-label": "Open chat", style: { color: buttonIconColor }, children: jsxRuntime.jsx("div", { className: "ai-chat-button-svg", children: jsxRuntime.jsx(IconComponent, {}) }) }));
|
|
22027
|
+
})()] }) }));
|
|
21669
22028
|
};
|
|
21670
22029
|
|
|
21671
22030
|
exports.ApiError = ApiError;
|