@chatwidgetai/chat-widget 0.1.2 → 0.1.3
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 +359 -25
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +359 -25
- package/dist/index.js.map +1 -1
- package/dist/types/index.d.ts +111 -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.esm.js
CHANGED
|
@@ -416,9 +416,16 @@ function useChat(options) {
|
|
|
416
416
|
// Load configuration on mount and hydrate with existing conversation if available
|
|
417
417
|
useEffect(() => {
|
|
418
418
|
let isMounted = true;
|
|
419
|
+
console.log('[useChat] Effect running, mounting component');
|
|
419
420
|
const initialize = async () => {
|
|
420
421
|
try {
|
|
422
|
+
console.log('[useChat] Fetching config...');
|
|
421
423
|
const config = await apiClient.current.getConfig();
|
|
424
|
+
console.log('[useChat] Config fetched successfully:', {
|
|
425
|
+
hasAppearance: !!config.appearance,
|
|
426
|
+
hasLightMode: !!config.appearance?.lightMode,
|
|
427
|
+
hasDarkMode: !!config.appearance?.darkMode,
|
|
428
|
+
});
|
|
422
429
|
const persistConversation = config.behavior.persistConversation ?? true;
|
|
423
430
|
let conversationId = '';
|
|
424
431
|
let messages = [];
|
|
@@ -437,8 +444,10 @@ function useChat(options) {
|
|
|
437
444
|
}
|
|
438
445
|
}
|
|
439
446
|
if (!isMounted) {
|
|
447
|
+
console.log('[useChat] Component unmounted, skipping state update');
|
|
440
448
|
return;
|
|
441
449
|
}
|
|
450
|
+
console.log('[useChat] Setting config in state');
|
|
442
451
|
setState(prev => ({
|
|
443
452
|
...prev,
|
|
444
453
|
config,
|
|
@@ -447,6 +456,7 @@ function useChat(options) {
|
|
|
447
456
|
}));
|
|
448
457
|
}
|
|
449
458
|
catch (error) {
|
|
459
|
+
console.error('[useChat] Error fetching config:', error);
|
|
450
460
|
if (!isMounted) {
|
|
451
461
|
return;
|
|
452
462
|
}
|
|
@@ -458,6 +468,7 @@ function useChat(options) {
|
|
|
458
468
|
};
|
|
459
469
|
initialize();
|
|
460
470
|
return () => {
|
|
471
|
+
console.log('[useChat] Effect cleanup, unmounting component');
|
|
461
472
|
isMounted = false;
|
|
462
473
|
};
|
|
463
474
|
}, [widgetId, apiKey, apiUrl, onError]);
|
|
@@ -21431,7 +21442,7 @@ const TypingIndicator = () => {
|
|
|
21431
21442
|
return (jsx("div", { className: "ai-chat-message assistant", children: jsxs("div", { className: "ai-chat-typing", children: [jsx("span", { className: "ai-chat-typing-dot" }), jsx("span", { className: "ai-chat-typing-dot" }), jsx("span", { className: "ai-chat-typing-dot" })] }) }));
|
|
21432
21443
|
};
|
|
21433
21444
|
|
|
21434
|
-
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, }) => {
|
|
21435
21446
|
const messagesEndRef = useRef(null);
|
|
21436
21447
|
// Auto-scroll to bottom when new messages arrive
|
|
21437
21448
|
useEffect(() => {
|
|
@@ -21451,7 +21462,7 @@ const MessageList = ({ messages, isTyping = false, showTypingIndicator = true, s
|
|
|
21451
21462
|
}
|
|
21452
21463
|
return map;
|
|
21453
21464
|
}, [messages]);
|
|
21454
|
-
return (jsxs("div", { className: "ai-chat-messages", role: "log", "aria-live": "polite", "aria-atomic": "false", children: [messages.length === 0 && welcomeMessage && (jsxs("div", { className: "ai-chat-welcome", children: [jsx("div", { className: "ai-chat-welcome-title", children:
|
|
21465
|
+
return (jsxs("div", { className: "ai-chat-messages", role: "log", "aria-live": "polite", "aria-atomic": "false", children: [messages.length === 0 && (welcomeTitle || welcomeMessage) && (jsxs("div", { className: "ai-chat-welcome", children: [welcomeTitle && (jsx("div", { className: "ai-chat-welcome-title", children: welcomeTitle })), welcomeMessage && (jsx("div", { className: "ai-chat-welcome-text", children: welcomeMessage }))] })), messages.map((message) => (jsx(Message, { message: message, showTimestamp: showTimestamps, enableFeedback: enableFeedback, showSources: showSources, sourceDisplayMode: sourceDisplayMode, toolCallNameById: toolCallNameById, onFeedback: onFeedback }, message.id))), isTyping && showTypingIndicator && jsx(TypingIndicator, {}), jsx("div", { ref: messagesEndRef })] }));
|
|
21455
21466
|
};
|
|
21456
21467
|
|
|
21457
21468
|
// Allowed file types
|
|
@@ -21477,7 +21488,7 @@ const formatFileSize = (bytes) => {
|
|
|
21477
21488
|
return (bytes / 1024).toFixed(1) + ' KB';
|
|
21478
21489
|
return (bytes / (1024 * 1024)).toFixed(1) + ' MB';
|
|
21479
21490
|
};
|
|
21480
|
-
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, }) => {
|
|
21481
21492
|
const [value, setValue] = useState('');
|
|
21482
21493
|
const [selectedFiles, setSelectedFiles] = useState([]);
|
|
21483
21494
|
const textareaRef = useRef(null);
|
|
@@ -21535,7 +21546,8 @@ const MessageInput = ({ onSend, placeholder = 'Type your message...', disabled =
|
|
|
21535
21546
|
textareaRef.current.style.height = `${textareaRef.current.scrollHeight}px`;
|
|
21536
21547
|
}
|
|
21537
21548
|
};
|
|
21538
|
-
|
|
21549
|
+
console.log('[MessageInput] separateFromChat:', separateFromChat, 'class:', separateFromChat ? 'separate' : 'integrated');
|
|
21550
|
+
return (jsxs("div", { className: `ai-chat-input-container ${separateFromChat ? 'separate' : 'integrated'}`, children: [selectedFiles.length > 0 && (jsx("div", { className: "ai-chat-file-list", children: selectedFiles.map((file, index) => {
|
|
21539
21551
|
const ext = getFileExtension(file.name);
|
|
21540
21552
|
return (jsxs("div", { className: "ai-chat-file-item", children: [jsx("span", { className: "ai-chat-file-extension", children: ext }), jsxs("div", { className: "ai-chat-file-info", children: [jsx("span", { className: "ai-chat-file-name", children: file.name }), jsx("span", { className: "ai-chat-file-size", children: formatFileSize(file.size) })] }), jsx("button", { className: "ai-chat-file-remove", onClick: () => handleRemoveFile(index), "aria-label": "Remove file", children: "\u00D7" })] }, index));
|
|
21541
21553
|
}) })), jsxs("div", { className: "ai-chat-input-wrapper", children: [enableFileUpload && (jsxs(Fragment, { children: [jsx("input", { ref: fileInputRef, type: "file", onChange: handleFileSelect, style: { display: 'none' }, multiple: true, accept: ALLOWED_EXTENSIONS.join(','), "aria-label": "File input" }), jsx("button", { className: "ai-chat-file-button", onClick: () => fileInputRef.current?.click(), disabled: disabled, "aria-label": "Attach file", children: jsx("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: 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" }) }) })] })), jsx("textarea", { ref: textareaRef, className: "ai-chat-input", value: value, onChange: handleChange, onKeyDown: handleKeyDown, placeholder: placeholder, disabled: disabled, rows: 1, "aria-label": "Message input" }), jsx("button", { className: "ai-chat-send-button", onClick: handleSend, disabled: disabled || (!value.trim() && selectedFiles.length === 0), "aria-label": "Send message", children: jsxs("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsx("line", { x1: "22", y1: "2", x2: "11", y2: "13" }), jsx("polygon", { points: "22 2 15 22 11 13 2 9 22 2" })] }) })] })] }));
|
|
@@ -21554,9 +21566,23 @@ const SuggestedQuestions = ({ questions, onQuestionClick, }) => {
|
|
|
21554
21566
|
};
|
|
21555
21567
|
|
|
21556
21568
|
const ChatWindow = ({ messages, isLoading, isTyping, error, config, onSendMessage, onClose, onFeedback, }) => {
|
|
21569
|
+
console.log('[ChatWindow] Rendering ChatWindow component');
|
|
21557
21570
|
const appearance = config?.appearance;
|
|
21558
21571
|
const behavior = config?.behavior;
|
|
21559
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...';
|
|
21560
21586
|
// Track if suggested questions should be shown
|
|
21561
21587
|
const [showSuggestedQuestions, setShowSuggestedQuestions] = useState(true);
|
|
21562
21588
|
// Hide suggested questions after first user message
|
|
@@ -21575,9 +21601,240 @@ const ChatWindow = ({ messages, isLoading, isTyping, error, config, onSendMessag
|
|
|
21575
21601
|
setShowSuggestedQuestions(false);
|
|
21576
21602
|
onSendMessage(question);
|
|
21577
21603
|
};
|
|
21578
|
-
return (jsxs("div", { className: `ai-chat-window size-${size}`, role: "dialog", "aria-label": "Chat window", children: [jsxs("div", { className: "ai-chat-header", children: [jsxs("div", { className: "ai-chat-header-content", children: [appearance?.logo && (jsx("img", { src: appearance.logo, alt: "Logo", className: "ai-chat-logo" })), jsx("div", { className: "ai-chat-title", children:
|
|
21604
|
+
return (jsxs("div", { className: `ai-chat-window size-${size}`, role: "dialog", "aria-label": "Chat window", children: [jsxs("div", { className: "ai-chat-header", children: [jsxs("div", { className: "ai-chat-header-content", children: [appearance?.logo && (jsx("img", { src: appearance.logo, alt: "Logo", className: "ai-chat-logo" })), jsx("div", { className: "ai-chat-title", children: headerTitle })] }), jsx("button", { className: "ai-chat-close-button", onClick: onClose, "aria-label": "Close chat", children: jsxs("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsx("line", { x1: "18", y1: "6", x2: "6", y2: "18" }), jsx("line", { x1: "6", y1: "6", x2: "18", y2: "18" })] }) })] }), error && (jsx("div", { className: "ai-chat-error", role: "alert", children: error })), maxMessages && userMessageCount >= maxMessages - 2 && !isLimitReached && (jsxs("div", { className: "ai-chat-warning", role: "alert", children: [maxMessages - userMessageCount, " message", maxMessages - userMessageCount !== 1 ? 's' : '', " remaining in this session"] })), isLimitReached && (jsxs("div", { className: "ai-chat-error", role: "alert", children: ["Message limit reached (", maxMessages, " messages per session). Please start a new conversation."] })), 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 && (jsx(SuggestedQuestions, { questions: behavior.suggestedQuestions, onQuestionClick: handleQuestionClick })), jsx(MessageInput, { onSend: onSendMessage, placeholder: isLimitReached ? 'Message limit reached' : inputPlaceholder, disabled: isLoading || isLimitReached, enableFileUpload: behavior?.enableFileUpload, separateFromChat: themeConfig?.footer?.separateFromChat })] }));
|
|
21579
21605
|
};
|
|
21580
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.borderRadius !== undefined)
|
|
21649
|
+
styles['--button-border-radius'] = `${btn.borderRadius}px`;
|
|
21650
|
+
if (btn.borderWidth !== undefined)
|
|
21651
|
+
styles['--button-border-width'] = `${btn.borderWidth}px`;
|
|
21652
|
+
if (btn.borderColor)
|
|
21653
|
+
styles['--button-border-color'] = btn.borderColor;
|
|
21654
|
+
if (btn.borderOpacity !== undefined)
|
|
21655
|
+
styles['--button-border-opacity'] = btn.borderOpacity.toString();
|
|
21656
|
+
if (btn.backdropBlur !== undefined)
|
|
21657
|
+
styles['--button-backdrop-blur'] = `${btn.backdropBlur}px`;
|
|
21658
|
+
if (btn.shadow)
|
|
21659
|
+
styles['--button-shadow'] = getShadowValue(btn.shadow);
|
|
21660
|
+
// ========================================================================
|
|
21661
|
+
// CARD/WINDOW APPEARANCE
|
|
21662
|
+
// ========================================================================
|
|
21663
|
+
const card = themeConfig.card;
|
|
21664
|
+
if (card.backgroundColor)
|
|
21665
|
+
styles['--card-background'] = card.backgroundColor;
|
|
21666
|
+
if (card.opacity !== undefined)
|
|
21667
|
+
styles['--card-opacity'] = card.opacity.toString();
|
|
21668
|
+
if (card.borderRadius !== undefined)
|
|
21669
|
+
styles['--card-border-radius'] = `${card.borderRadius}px`;
|
|
21670
|
+
if (card.borderWidth !== undefined)
|
|
21671
|
+
styles['--card-border-width'] = `${card.borderWidth}px`;
|
|
21672
|
+
if (card.borderColor) {
|
|
21673
|
+
styles['--card-border-color'] = card.borderColor;
|
|
21674
|
+
// Create rgba border color with opacity for box-shadow
|
|
21675
|
+
if (card.borderOpacity !== undefined) {
|
|
21676
|
+
const opacity = card.borderOpacity;
|
|
21677
|
+
// Convert hex to rgba
|
|
21678
|
+
const hex = card.borderColor.replace('#', '');
|
|
21679
|
+
const r = parseInt(hex.substring(0, 2), 16);
|
|
21680
|
+
const g = parseInt(hex.substring(2, 4), 16);
|
|
21681
|
+
const b = parseInt(hex.substring(4, 6), 16);
|
|
21682
|
+
styles['--card-border-color-rgba'] = `rgba(${r}, ${g}, ${b}, ${opacity})`;
|
|
21683
|
+
}
|
|
21684
|
+
}
|
|
21685
|
+
if (card.borderOpacity !== undefined)
|
|
21686
|
+
styles['--card-border-opacity'] = card.borderOpacity.toString();
|
|
21687
|
+
if (card.backdropBlur !== undefined)
|
|
21688
|
+
styles['--card-backdrop-blur'] = `${card.backdropBlur}px`;
|
|
21689
|
+
if (card.shadow)
|
|
21690
|
+
styles['--card-shadow'] = getShadowValue(card.shadow);
|
|
21691
|
+
// ========================================================================
|
|
21692
|
+
// HEADER APPEARANCE
|
|
21693
|
+
// ========================================================================
|
|
21694
|
+
const header = themeConfig.header;
|
|
21695
|
+
if (header.backgroundColor)
|
|
21696
|
+
styles['--header-background'] = header.backgroundColor;
|
|
21697
|
+
if (header.opacity !== undefined)
|
|
21698
|
+
styles['--header-opacity'] = header.opacity.toString();
|
|
21699
|
+
if (header.textColor)
|
|
21700
|
+
styles['--header-text-color'] = header.textColor;
|
|
21701
|
+
if (header.borderBottomWidth !== undefined)
|
|
21702
|
+
styles['--header-border-bottom-width'] = `${header.borderBottomWidth}px`;
|
|
21703
|
+
if (header.borderBottomColor)
|
|
21704
|
+
styles['--header-border-bottom-color'] = header.borderBottomColor;
|
|
21705
|
+
if (header.borderBottomOpacity !== undefined)
|
|
21706
|
+
styles['--header-border-bottom-opacity'] = header.borderBottomOpacity.toString();
|
|
21707
|
+
// ========================================================================
|
|
21708
|
+
// CHAT APPEARANCE
|
|
21709
|
+
// ========================================================================
|
|
21710
|
+
const chat = themeConfig.chat;
|
|
21711
|
+
if (chat.backgroundColor)
|
|
21712
|
+
styles['--chat-background'] = chat.backgroundColor;
|
|
21713
|
+
if (chat.opacity !== undefined)
|
|
21714
|
+
styles['--chat-opacity'] = chat.opacity.toString();
|
|
21715
|
+
// Welcome message
|
|
21716
|
+
if (chat.welcomeColor)
|
|
21717
|
+
styles['--welcome-color'] = chat.welcomeColor;
|
|
21718
|
+
// Message bubbles
|
|
21719
|
+
if (chat.enableBubbles) {
|
|
21720
|
+
if (chat.bubbleUserColor)
|
|
21721
|
+
styles['--bubble-user-color'] = chat.bubbleUserColor;
|
|
21722
|
+
if (chat.bubbleUserOpacity !== undefined)
|
|
21723
|
+
styles['--bubble-user-opacity'] = chat.bubbleUserOpacity.toString();
|
|
21724
|
+
if (chat.bubbleAssistantColor)
|
|
21725
|
+
styles['--bubble-assistant-color'] = chat.bubbleAssistantColor;
|
|
21726
|
+
if (chat.bubbleAssistantOpacity !== undefined)
|
|
21727
|
+
styles['--bubble-assistant-opacity'] = chat.bubbleAssistantOpacity.toString();
|
|
21728
|
+
if (chat.bubbleBorderWidth !== undefined)
|
|
21729
|
+
styles['--bubble-border-width'] = `${chat.bubbleBorderWidth}px`;
|
|
21730
|
+
if (chat.bubbleBorderColor)
|
|
21731
|
+
styles['--bubble-border-color'] = chat.bubbleBorderColor;
|
|
21732
|
+
if (chat.bubbleBorderOpacity !== undefined)
|
|
21733
|
+
styles['--bubble-border-opacity'] = chat.bubbleBorderOpacity.toString();
|
|
21734
|
+
}
|
|
21735
|
+
else {
|
|
21736
|
+
// Plain text mode
|
|
21737
|
+
if (chat.textColor)
|
|
21738
|
+
styles['--message-text-color'] = chat.textColor;
|
|
21739
|
+
}
|
|
21740
|
+
// ========================================================================
|
|
21741
|
+
// FOOTER APPEARANCE
|
|
21742
|
+
// ========================================================================
|
|
21743
|
+
const footer = themeConfig.footer;
|
|
21744
|
+
// Only if separate from chat
|
|
21745
|
+
if (footer.separateFromChat) {
|
|
21746
|
+
if (footer.backgroundColor)
|
|
21747
|
+
styles['--footer-background'] = footer.backgroundColor;
|
|
21748
|
+
if (footer.opacity !== undefined)
|
|
21749
|
+
styles['--footer-opacity'] = footer.opacity.toString();
|
|
21750
|
+
if (footer.borderTopWidth !== undefined)
|
|
21751
|
+
styles['--footer-border-top-width'] = `${footer.borderTopWidth}px`;
|
|
21752
|
+
if (footer.borderTopColor)
|
|
21753
|
+
styles['--footer-border-top-color'] = footer.borderTopColor;
|
|
21754
|
+
if (footer.borderTopOpacity !== undefined)
|
|
21755
|
+
styles['--footer-border-top-opacity'] = footer.borderTopOpacity.toString();
|
|
21756
|
+
}
|
|
21757
|
+
// Backdrop blur (only when floating)
|
|
21758
|
+
if (!footer.separateFromChat && footer.backdropBlur !== undefined) {
|
|
21759
|
+
styles['--footer-backdrop-blur'] = `${footer.backdropBlur}px`;
|
|
21760
|
+
}
|
|
21761
|
+
// Input field
|
|
21762
|
+
if (footer.inputBackgroundColor)
|
|
21763
|
+
styles['--input-background'] = footer.inputBackgroundColor;
|
|
21764
|
+
if (footer.inputBackgroundOpacity !== undefined)
|
|
21765
|
+
styles['--input-background-opacity'] = footer.inputBackgroundOpacity.toString();
|
|
21766
|
+
if (footer.inputBorderRadius !== undefined)
|
|
21767
|
+
styles['--input-border-radius'] = `${footer.inputBorderRadius}px`;
|
|
21768
|
+
if (footer.inputBorderWidth !== undefined)
|
|
21769
|
+
styles['--input-border-width'] = `${footer.inputBorderWidth}px`;
|
|
21770
|
+
if (footer.inputBorderColor)
|
|
21771
|
+
styles['--input-border-color'] = footer.inputBorderColor;
|
|
21772
|
+
if (footer.inputBorderOpacity !== undefined)
|
|
21773
|
+
styles['--input-border-opacity'] = footer.inputBorderOpacity.toString();
|
|
21774
|
+
if (footer.inputShadow)
|
|
21775
|
+
styles['--input-shadow'] = getShadowValue(footer.inputShadow);
|
|
21776
|
+
// Send button
|
|
21777
|
+
if (footer.buttonBackgroundColor)
|
|
21778
|
+
styles['--send-button-background'] = footer.buttonBackgroundColor;
|
|
21779
|
+
if (footer.buttonOpacity !== undefined)
|
|
21780
|
+
styles['--send-button-opacity'] = footer.buttonOpacity.toString();
|
|
21781
|
+
if (footer.buttonBorderRadius !== undefined)
|
|
21782
|
+
styles['--send-button-border-radius'] = `${footer.buttonBorderRadius}px`;
|
|
21783
|
+
if (footer.buttonBorderWidth !== undefined)
|
|
21784
|
+
styles['--send-button-border-width'] = `${footer.buttonBorderWidth}px`;
|
|
21785
|
+
if (footer.buttonBorderColor)
|
|
21786
|
+
styles['--send-button-border-color'] = footer.buttonBorderColor;
|
|
21787
|
+
if (footer.buttonBorderOpacity !== undefined)
|
|
21788
|
+
styles['--send-button-border-opacity'] = footer.buttonBorderOpacity.toString();
|
|
21789
|
+
// ========================================================================
|
|
21790
|
+
// HOVER STATES
|
|
21791
|
+
// ========================================================================
|
|
21792
|
+
const hover = themeConfig.hover;
|
|
21793
|
+
if (hover.buttonScale !== undefined)
|
|
21794
|
+
styles['--hover-button-scale'] = hover.buttonScale.toString();
|
|
21795
|
+
if (hover.buttonOpacity !== undefined)
|
|
21796
|
+
styles['--hover-button-opacity'] = hover.buttonOpacity.toString();
|
|
21797
|
+
if (hover.inputBorderColor)
|
|
21798
|
+
styles['--hover-input-border-color'] = hover.inputBorderColor;
|
|
21799
|
+
if (hover.sendButtonOpacity !== undefined)
|
|
21800
|
+
styles['--hover-send-button-opacity'] = hover.sendButtonOpacity.toString();
|
|
21801
|
+
if (hover.closeButtonOpacity !== undefined)
|
|
21802
|
+
styles['--hover-close-button-opacity'] = hover.closeButtonOpacity.toString();
|
|
21803
|
+
// ========================================================================
|
|
21804
|
+
// ACTIVE STATES
|
|
21805
|
+
// ========================================================================
|
|
21806
|
+
const active = themeConfig.active;
|
|
21807
|
+
if (active.inputBorderColor)
|
|
21808
|
+
styles['--active-input-border-color'] = active.inputBorderColor;
|
|
21809
|
+
if (active.inputShadow)
|
|
21810
|
+
styles['--active-input-shadow'] = active.inputShadow;
|
|
21811
|
+
}
|
|
21812
|
+
else {
|
|
21813
|
+
// Fallback to legacy fields if no theme config
|
|
21814
|
+
if (appearance.primaryColor)
|
|
21815
|
+
styles['--primary-color'] = appearance.primaryColor;
|
|
21816
|
+
if (appearance.borderRadius !== undefined)
|
|
21817
|
+
styles['--border-radius'] = `${appearance.borderRadius}px`;
|
|
21818
|
+
// Legacy button
|
|
21819
|
+
if (appearance.button) {
|
|
21820
|
+
const btn = appearance.button;
|
|
21821
|
+
if (btn.color)
|
|
21822
|
+
styles['--button-color'] = btn.color;
|
|
21823
|
+
if (btn.size)
|
|
21824
|
+
styles['--button-size'] = `${btn.size}px`;
|
|
21825
|
+
if (btn.borderRadius !== undefined)
|
|
21826
|
+
styles['--button-border-radius'] = `${btn.borderRadius}px`;
|
|
21827
|
+
if (btn.borderWidth !== undefined)
|
|
21828
|
+
styles['--button-border-width'] = `${btn.borderWidth}px`;
|
|
21829
|
+
if (btn.borderColor)
|
|
21830
|
+
styles['--button-border-color'] = btn.borderColor;
|
|
21831
|
+
if (btn.opacity !== undefined)
|
|
21832
|
+
styles['--button-opacity'] = btn.opacity.toString();
|
|
21833
|
+
}
|
|
21834
|
+
}
|
|
21835
|
+
return styles;
|
|
21836
|
+
}
|
|
21837
|
+
|
|
21581
21838
|
function styleInject(css, ref) {
|
|
21582
21839
|
if ( ref === void 0 ) ref = {};
|
|
21583
21840
|
var insertAt = ref.insertAt;
|
|
@@ -21605,11 +21862,12 @@ function styleInject(css, ref) {
|
|
|
21605
21862
|
}
|
|
21606
21863
|
}
|
|
21607
21864
|
|
|
21608
|
-
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)}}";
|
|
21865
|
+
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)}}";
|
|
21609
21866
|
styleInject(css_248z);
|
|
21610
21867
|
|
|
21611
21868
|
const ChatWidget = ({ widgetId, apiKey, apiUrl = window.location.origin, position = 'bottom-right', theme: themeOverride, primaryColor, onOpen, onClose, onMessage, onError, }) => {
|
|
21612
21869
|
const [isOpen, setIsOpen] = useState(false);
|
|
21870
|
+
const widgetRef = useRef(null);
|
|
21613
21871
|
const { messages, isLoading, isTyping, error, config, sendMessage, submitFeedback, } = useChat({
|
|
21614
21872
|
widgetId,
|
|
21615
21873
|
apiKey,
|
|
@@ -21617,6 +21875,21 @@ const ChatWidget = ({ widgetId, apiKey, apiUrl = window.location.origin, positio
|
|
|
21617
21875
|
onMessage,
|
|
21618
21876
|
onError,
|
|
21619
21877
|
});
|
|
21878
|
+
// Debug logging
|
|
21879
|
+
useEffect(() => {
|
|
21880
|
+
console.log('[ChatWidget] Config loaded:', config ? 'YES' : 'NO');
|
|
21881
|
+
if (config) {
|
|
21882
|
+
console.log('[ChatWidget] Config details:', {
|
|
21883
|
+
theme: config.appearance?.theme,
|
|
21884
|
+
darkModeEnabled: config.appearance?.darkModeEnabled,
|
|
21885
|
+
hasLightMode: !!config.appearance?.lightMode,
|
|
21886
|
+
hasDarkMode: !!config.appearance?.darkMode,
|
|
21887
|
+
});
|
|
21888
|
+
}
|
|
21889
|
+
}, [config]);
|
|
21890
|
+
useEffect(() => {
|
|
21891
|
+
console.log('[ChatWidget] isOpen changed:', isOpen);
|
|
21892
|
+
}, [isOpen]);
|
|
21620
21893
|
// Handle auto-open
|
|
21621
21894
|
useEffect(() => {
|
|
21622
21895
|
if (config?.behavior.autoOpen) {
|
|
@@ -21629,26 +21902,84 @@ const ChatWidget = ({ widgetId, apiKey, apiUrl = window.location.origin, positio
|
|
|
21629
21902
|
}
|
|
21630
21903
|
return undefined;
|
|
21631
21904
|
}, [config, onOpen]);
|
|
21905
|
+
// Handle close on outside click
|
|
21906
|
+
useEffect(() => {
|
|
21907
|
+
if (!isOpen || !config?.appearance.closeOnOutsideClick)
|
|
21908
|
+
return;
|
|
21909
|
+
const handleClickOutside = (event) => {
|
|
21910
|
+
if (widgetRef.current && !widgetRef.current.contains(event.target)) {
|
|
21911
|
+
console.log('[ChatWidget] Closing due to outside click');
|
|
21912
|
+
setIsOpen(false);
|
|
21913
|
+
onClose?.();
|
|
21914
|
+
}
|
|
21915
|
+
};
|
|
21916
|
+
// Add slight delay to avoid immediate close on open
|
|
21917
|
+
const timer = setTimeout(() => {
|
|
21918
|
+
document.addEventListener('mousedown', handleClickOutside);
|
|
21919
|
+
}, 100);
|
|
21920
|
+
return () => {
|
|
21921
|
+
clearTimeout(timer);
|
|
21922
|
+
document.removeEventListener('mousedown', handleClickOutside);
|
|
21923
|
+
};
|
|
21924
|
+
}, [isOpen, config, onClose]);
|
|
21925
|
+
// Handle close on Escape key
|
|
21926
|
+
useEffect(() => {
|
|
21927
|
+
if (!isOpen || !config?.appearance.closeOnEscape)
|
|
21928
|
+
return;
|
|
21929
|
+
const handleEscapeKey = (event) => {
|
|
21930
|
+
if (event.key === 'Escape') {
|
|
21931
|
+
setIsOpen(false);
|
|
21932
|
+
onClose?.();
|
|
21933
|
+
}
|
|
21934
|
+
};
|
|
21935
|
+
document.addEventListener('keydown', handleEscapeKey);
|
|
21936
|
+
return () => document.removeEventListener('keydown', handleEscapeKey);
|
|
21937
|
+
}, [isOpen, config, onClose]);
|
|
21632
21938
|
// Determine theme
|
|
21633
|
-
const
|
|
21634
|
-
const
|
|
21635
|
-
|
|
21636
|
-
|
|
21939
|
+
const appearanceConfig = config?.appearance;
|
|
21940
|
+
const themeSetting = themeOverride || appearanceConfig?.theme || 'light';
|
|
21941
|
+
const canUseDarkMode = appearanceConfig?.darkModeEnabled !== false;
|
|
21942
|
+
// Only check system preference if dark mode is enabled
|
|
21943
|
+
const systemPrefersDark = canUseDarkMode && typeof window !== "undefined"
|
|
21944
|
+
? window.matchMedia('(prefers-color-scheme: dark)').matches
|
|
21945
|
+
: false;
|
|
21946
|
+
const effectiveTheme = !canUseDarkMode
|
|
21947
|
+
? 'light' // Force light mode if dark mode is disabled
|
|
21948
|
+
: themeSetting === 'auto'
|
|
21949
|
+
? (systemPrefersDark ? 'dark' : 'light')
|
|
21950
|
+
: themeSetting === 'dark'
|
|
21951
|
+
? 'dark'
|
|
21952
|
+
: 'light';
|
|
21637
21953
|
// Determine position (config takes priority over prop)
|
|
21638
21954
|
const effectivePosition = config?.appearance.position || position;
|
|
21639
|
-
// Apply custom styles
|
|
21640
|
-
|
|
21641
|
-
|
|
21642
|
-
|
|
21643
|
-
|
|
21644
|
-
if
|
|
21645
|
-
|
|
21646
|
-
|
|
21647
|
-
|
|
21648
|
-
|
|
21649
|
-
|
|
21955
|
+
// Apply custom styles from appearance configuration
|
|
21956
|
+
// Use the correct theme configuration (lightMode or darkMode)
|
|
21957
|
+
const customStyles = appearanceConfig
|
|
21958
|
+
? applyAppearanceStyles(appearanceConfig, effectiveTheme)
|
|
21959
|
+
: {};
|
|
21960
|
+
// Override with prop values if provided
|
|
21961
|
+
if (primaryColor) {
|
|
21962
|
+
customStyles['--primary-color'] = primaryColor;
|
|
21963
|
+
}
|
|
21964
|
+
// Debug logging for theme and styles
|
|
21965
|
+
useEffect(() => {
|
|
21966
|
+
console.log('[ChatWidget] Theme info:', {
|
|
21967
|
+
effectiveTheme,
|
|
21968
|
+
canUseDarkMode,
|
|
21969
|
+
themeSetting,
|
|
21970
|
+
systemPrefersDark,
|
|
21971
|
+
hasCustomStyles: Object.keys(customStyles).length > 0,
|
|
21972
|
+
buttonColor: customStyles['--button-color'],
|
|
21973
|
+
buttonSize: customStyles['--button-size'],
|
|
21974
|
+
cardBackground: customStyles['--card-background'],
|
|
21975
|
+
cardOpacity: customStyles['--card-opacity'],
|
|
21976
|
+
cardBorderRadius: customStyles['--card-border-radius'],
|
|
21977
|
+
});
|
|
21978
|
+
console.log('[ChatWidget] All CSS variables:', customStyles);
|
|
21979
|
+
}, [effectiveTheme, customStyles]);
|
|
21650
21980
|
const handleToggle = () => {
|
|
21651
21981
|
const newState = !isOpen;
|
|
21982
|
+
console.log('[ChatWidget] handleToggle called, setting isOpen to:', newState);
|
|
21652
21983
|
setIsOpen(newState);
|
|
21653
21984
|
if (newState) {
|
|
21654
21985
|
onOpen?.();
|
|
@@ -21660,10 +21991,13 @@ const ChatWidget = ({ widgetId, apiKey, apiUrl = window.location.origin, positio
|
|
|
21660
21991
|
const handleFeedback = async (messageId, feedback) => {
|
|
21661
21992
|
await submitFeedback(messageId, feedback);
|
|
21662
21993
|
};
|
|
21663
|
-
|
|
21664
|
-
|
|
21665
|
-
|
|
21666
|
-
|
|
21994
|
+
// Don't render until config is loaded to avoid flash of unstyled content
|
|
21995
|
+
if (!config) {
|
|
21996
|
+
console.log('[ChatWidget] Not rendering - config not loaded yet');
|
|
21997
|
+
return null;
|
|
21998
|
+
}
|
|
21999
|
+
console.log('[ChatWidget] Rendering widget', { isOpen, hasConfig: !!config });
|
|
22000
|
+
return (jsx("div", { className: `ai-chat-widget ${effectiveTheme}`, style: customStyles, children: jsxs("div", { ref: widgetRef, className: `ai-chat-widget-container ${effectivePosition}`, children: [isOpen && (jsx(ChatWindow, { messages: messages, isLoading: isLoading, isTyping: isTyping, error: error, config: config, onSendMessage: sendMessage, onClose: handleToggle, onFeedback: handleFeedback })), !isOpen && (jsx("button", { className: "ai-chat-button", onClick: handleToggle, "aria-label": "Open chat", children: config?.appearance.buttonIcon ? (jsx("span", { className: "ai-chat-button-icon", children: config.appearance.buttonIcon })) : (jsx("svg", { className: "ai-chat-button-svg", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: 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" }) })) }))] }) }));
|
|
21667
22001
|
};
|
|
21668
22002
|
|
|
21669
22003
|
export { ApiError, ChatWidget, useChat };
|