@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/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]);
@@ -2451,7 +2462,7 @@ function requireCjs$1 () {
2451
2462
  };
2452
2463
  Object.defineProperty(cjs$1, "__esModule", { value: true });
2453
2464
  cjs$1.default = StyleToObject;
2454
- const inline_style_parser_1 = __importDefault(requireInlineStyleParser());
2465
+ var inline_style_parser_1 = __importDefault(requireInlineStyleParser());
2455
2466
  /**
2456
2467
  * Parses inline style to object.
2457
2468
  *
@@ -2467,17 +2478,17 @@ function requireCjs$1 () {
2467
2478
  * ```
2468
2479
  */
2469
2480
  function StyleToObject(style, iterator) {
2470
- let styleObject = null;
2481
+ var styleObject = null;
2471
2482
  if (!style || typeof style !== 'string') {
2472
2483
  return styleObject;
2473
2484
  }
2474
- const declarations = (0, inline_style_parser_1.default)(style);
2475
- const hasIterator = typeof iterator === 'function';
2476
- declarations.forEach((declaration) => {
2485
+ var declarations = (0, inline_style_parser_1.default)(style);
2486
+ var hasIterator = typeof iterator === 'function';
2487
+ declarations.forEach(function (declaration) {
2477
2488
  if (declaration.type !== 'declaration') {
2478
2489
  return;
2479
2490
  }
2480
- const { property, value } = declaration;
2491
+ var property = declaration.property, value = declaration.value;
2481
2492
  if (hasIterator) {
2482
2493
  iterator(property, value, declaration);
2483
2494
  }
@@ -17518,7 +17529,8 @@ function footer(state) {
17518
17529
  }
17519
17530
 
17520
17531
  /**
17521
- * @import {Node, Parent} from 'unist'
17532
+ * @typedef {import('unist').Node} Node
17533
+ * @typedef {import('unist').Parent} Parent
17522
17534
  */
17523
17535
 
17524
17536
 
@@ -17566,11 +17578,7 @@ const convert =
17566
17578
  }
17567
17579
 
17568
17580
  if (typeof test === 'object') {
17569
- return Array.isArray(test)
17570
- ? anyFactory(test)
17571
- : // Cast because `ReadonlyArray` goes into the above but `isArray`
17572
- // narrows to `Array`.
17573
- propertiesFactory(/** @type {Props} */ (test))
17581
+ return Array.isArray(test) ? anyFactory(test) : propsFactory(test)
17574
17582
  }
17575
17583
 
17576
17584
  if (typeof test === 'string') {
@@ -17617,7 +17625,7 @@ function anyFactory(tests) {
17617
17625
  * @param {Props} check
17618
17626
  * @returns {Check}
17619
17627
  */
17620
- function propertiesFactory(check) {
17628
+ function propsFactory(check) {
17621
17629
  const checkAsRecord = /** @type {Record<string, unknown>} */ (check);
17622
17630
 
17623
17631
  return castFactory(all)
@@ -17706,7 +17714,8 @@ function color(d) {
17706
17714
  }
17707
17715
 
17708
17716
  /**
17709
- * @import {Node as UnistNode, Parent as UnistParent} from 'unist'
17717
+ * @typedef {import('unist').Node} UnistNode
17718
+ * @typedef {import('unist').Parent} UnistParent
17710
17719
  */
17711
17720
 
17712
17721
 
@@ -17809,9 +17818,9 @@ function visitParents(tree, test, visitor, reverse) {
17809
17818
  typeof value.tagName === 'string'
17810
17819
  ? value.tagName
17811
17820
  : // `xast`
17812
- typeof value.name === 'string'
17813
- ? value.name
17814
- : undefined;
17821
+ typeof value.name === 'string'
17822
+ ? value.name
17823
+ : undefined;
17815
17824
 
17816
17825
  Object.defineProperty(visit, 'name', {
17817
17826
  value:
@@ -21431,7 +21440,7 @@ const TypingIndicator = () => {
21431
21440
  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
21441
  };
21433
21442
 
21434
- const MessageList = ({ messages, isTyping = false, showTypingIndicator = true, showTimestamps = true, enableFeedback = true, showSources = true, sourceDisplayMode = 'with-score', welcomeMessage, onFeedback, }) => {
21443
+ const MessageList = ({ messages, isTyping = false, showTypingIndicator = true, showTimestamps = true, enableFeedback = true, showSources = true, sourceDisplayMode = 'with-score', welcomeTitle, welcomeMessage, onFeedback, }) => {
21435
21444
  const messagesEndRef = useRef(null);
21436
21445
  // Auto-scroll to bottom when new messages arrive
21437
21446
  useEffect(() => {
@@ -21451,7 +21460,7 @@ const MessageList = ({ messages, isTyping = false, showTypingIndicator = true, s
21451
21460
  }
21452
21461
  return map;
21453
21462
  }, [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: "Welcome!" }), 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 })] }));
21463
+ 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
21464
  };
21456
21465
 
21457
21466
  // Allowed file types
@@ -21477,7 +21486,7 @@ const formatFileSize = (bytes) => {
21477
21486
  return (bytes / 1024).toFixed(1) + ' KB';
21478
21487
  return (bytes / (1024 * 1024)).toFixed(1) + ' MB';
21479
21488
  };
21480
- const MessageInput = ({ onSend, placeholder = 'Type your message...', disabled = false, enableFileUpload = false, }) => {
21489
+ const MessageInput = ({ onSend, placeholder = 'Type your message...', disabled = false, enableFileUpload = false, separateFromChat = true, }) => {
21481
21490
  const [value, setValue] = useState('');
21482
21491
  const [selectedFiles, setSelectedFiles] = useState([]);
21483
21492
  const textareaRef = useRef(null);
@@ -21535,7 +21544,8 @@ const MessageInput = ({ onSend, placeholder = 'Type your message...', disabled =
21535
21544
  textareaRef.current.style.height = `${textareaRef.current.scrollHeight}px`;
21536
21545
  }
21537
21546
  };
21538
- return (jsxs("div", { className: "ai-chat-input-container", children: [selectedFiles.length > 0 && (jsx("div", { className: "ai-chat-file-list", children: selectedFiles.map((file, index) => {
21547
+ console.log('[MessageInput] separateFromChat:', separateFromChat, 'class:', separateFromChat ? 'separate' : 'integrated');
21548
+ 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
21549
  const ext = getFileExtension(file.name);
21540
21550
  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
21551
  }) })), 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 +21564,23 @@ const SuggestedQuestions = ({ questions, onQuestionClick, }) => {
21554
21564
  };
21555
21565
 
21556
21566
  const ChatWindow = ({ messages, isLoading, isTyping, error, config, onSendMessage, onClose, onFeedback, }) => {
21567
+ console.log('[ChatWindow] Rendering ChatWindow component');
21557
21568
  const appearance = config?.appearance;
21558
21569
  const behavior = config?.behavior;
21559
21570
  const size = appearance?.size || 'medium';
21571
+ console.log('[ChatWindow] Size:', size, 'Appearance:', !!appearance);
21572
+ // Determine current theme config
21573
+ const themePreference = appearance?.theme ?? 'light';
21574
+ const canUseDarkMode = appearance?.darkModeEnabled !== false;
21575
+ const prefersDark = typeof window !== 'undefined' && window.matchMedia('(prefers-color-scheme: dark)').matches;
21576
+ const isDarkMode = themePreference === 'auto'
21577
+ ? (canUseDarkMode && prefersDark)
21578
+ : themePreference === 'dark' && canUseDarkMode;
21579
+ const themeConfig = (isDarkMode ? appearance?.darkMode : appearance?.lightMode) ?? (appearance?.lightMode || appearance?.darkMode);
21580
+ const headerTitle = themeConfig?.header?.title ?? appearance?.header?.title ?? appearance?.companyName ?? 'AI Assistant';
21581
+ const welcomeTitle = themeConfig?.chat?.welcomeTitle ?? 'Welcome!';
21582
+ const welcomeMessage = themeConfig?.chat?.welcomeMessage ?? appearance?.welcomeMessage ?? '👋 Hi there! How can I assist you today?';
21583
+ const inputPlaceholder = themeConfig?.footer?.inputPlaceholder ?? appearance?.placeholder ?? 'Ask me anything...';
21560
21584
  // Track if suggested questions should be shown
21561
21585
  const [showSuggestedQuestions, setShowSuggestedQuestions] = useState(true);
21562
21586
  // Hide suggested questions after first user message
@@ -21575,9 +21599,244 @@ const ChatWindow = ({ messages, isLoading, isTyping, error, config, onSendMessag
21575
21599
  setShowSuggestedQuestions(false);
21576
21600
  onSendMessage(question);
21577
21601
  };
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: appearance?.companyName || 'AI Assistant' })] }), 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, welcomeMessage: appearance?.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' : appearance?.placeholder, disabled: isLoading || isLimitReached, enableFileUpload: behavior?.enableFileUpload })] }));
21602
+ 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
21603
  };
21580
21604
 
21605
+ /**
21606
+ * Convert shadow size to CSS box-shadow value
21607
+ */
21608
+ function getShadowValue(size) {
21609
+ const shadows = {
21610
+ 'none': 'none',
21611
+ 'sm': '0 1px 2px 0 rgba(0, 0, 0, 0.05)',
21612
+ 'md': '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)',
21613
+ 'lg': '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)',
21614
+ 'xl': '0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)',
21615
+ '2xl': '0 25px 50px -12px rgba(0, 0, 0, 0.25)',
21616
+ };
21617
+ return shadows[size] || shadows.none;
21618
+ }
21619
+ /**
21620
+ * Apply appearance configuration as CSS custom properties
21621
+ * This allows the widget to be fully customizable via the appearance config
21622
+ *
21623
+ * @param appearance - Widget appearance configuration
21624
+ * @param theme - Current theme ('light' or 'dark')
21625
+ */
21626
+ function applyAppearanceStyles(appearance, theme = 'light') {
21627
+ const styles = {};
21628
+ // Global font family
21629
+ if (appearance.fontFamily) {
21630
+ styles.fontFamily = appearance.fontFamily;
21631
+ }
21632
+ // Select the correct theme configuration
21633
+ const themeConfig = theme === 'dark' ? appearance.darkMode : appearance.lightMode;
21634
+ // If theme config exists and has required properties, use it
21635
+ if (themeConfig && themeConfig.button) {
21636
+ // ========================================================================
21637
+ // BUTTON APPEARANCE
21638
+ // ========================================================================
21639
+ const btn = themeConfig.button;
21640
+ if (btn.color)
21641
+ styles['--button-color'] = btn.color;
21642
+ if (btn.opacity !== undefined)
21643
+ styles['--button-opacity'] = btn.opacity.toString();
21644
+ if (btn.size)
21645
+ styles['--button-size'] = `${btn.size}px`;
21646
+ if (btn.icon)
21647
+ styles['--button-icon'] = btn.icon;
21648
+ if (btn.iconColor)
21649
+ styles['--button-icon-color'] = btn.iconColor;
21650
+ if (btn.borderRadius !== undefined)
21651
+ styles['--button-border-radius'] = `${btn.borderRadius}px`;
21652
+ if (btn.borderWidth !== undefined)
21653
+ styles['--button-border-width'] = `${btn.borderWidth}px`;
21654
+ if (btn.borderColor)
21655
+ styles['--button-border-color'] = btn.borderColor;
21656
+ if (btn.borderOpacity !== undefined)
21657
+ styles['--button-border-opacity'] = btn.borderOpacity.toString();
21658
+ if (btn.backdropBlur !== undefined)
21659
+ styles['--button-backdrop-blur'] = `${btn.backdropBlur}px`;
21660
+ if (btn.shadow)
21661
+ styles['--button-shadow'] = getShadowValue(btn.shadow);
21662
+ // ========================================================================
21663
+ // CARD/WINDOW APPEARANCE
21664
+ // ========================================================================
21665
+ const card = themeConfig.card;
21666
+ if (card.backgroundColor)
21667
+ styles['--card-background'] = card.backgroundColor;
21668
+ if (card.opacity !== undefined)
21669
+ styles['--card-opacity'] = card.opacity.toString();
21670
+ if (card.borderRadius !== undefined)
21671
+ styles['--card-border-radius'] = `${card.borderRadius}px`;
21672
+ if (card.borderWidth !== undefined)
21673
+ styles['--card-border-width'] = `${card.borderWidth}px`;
21674
+ if (card.borderColor) {
21675
+ styles['--card-border-color'] = card.borderColor;
21676
+ // Create rgba border color with opacity for box-shadow
21677
+ if (card.borderOpacity !== undefined) {
21678
+ const opacity = card.borderOpacity;
21679
+ // Convert hex to rgba
21680
+ const hex = card.borderColor.replace('#', '');
21681
+ const r = parseInt(hex.substring(0, 2), 16);
21682
+ const g = parseInt(hex.substring(2, 4), 16);
21683
+ const b = parseInt(hex.substring(4, 6), 16);
21684
+ styles['--card-border-color-rgba'] = `rgba(${r}, ${g}, ${b}, ${opacity})`;
21685
+ }
21686
+ }
21687
+ if (card.borderOpacity !== undefined)
21688
+ styles['--card-border-opacity'] = card.borderOpacity.toString();
21689
+ if (card.backdropBlur !== undefined)
21690
+ styles['--card-backdrop-blur'] = `${card.backdropBlur}px`;
21691
+ if (card.shadow)
21692
+ styles['--card-shadow'] = getShadowValue(card.shadow);
21693
+ // ========================================================================
21694
+ // HEADER APPEARANCE
21695
+ // ========================================================================
21696
+ const header = themeConfig.header;
21697
+ if (header.backgroundColor)
21698
+ styles['--header-background'] = header.backgroundColor;
21699
+ if (header.opacity !== undefined)
21700
+ styles['--header-opacity'] = header.opacity.toString();
21701
+ if (header.textColor)
21702
+ styles['--header-text-color'] = header.textColor;
21703
+ if (header.borderBottomWidth !== undefined)
21704
+ styles['--header-border-bottom-width'] = `${header.borderBottomWidth}px`;
21705
+ if (header.borderBottomColor)
21706
+ styles['--header-border-bottom-color'] = header.borderBottomColor;
21707
+ if (header.borderBottomOpacity !== undefined)
21708
+ styles['--header-border-bottom-opacity'] = header.borderBottomOpacity.toString();
21709
+ // ========================================================================
21710
+ // CHAT APPEARANCE
21711
+ // ========================================================================
21712
+ const chat = themeConfig.chat;
21713
+ if (chat.backgroundColor)
21714
+ styles['--chat-background'] = chat.backgroundColor;
21715
+ if (chat.opacity !== undefined)
21716
+ styles['--chat-opacity'] = chat.opacity.toString();
21717
+ // Welcome message
21718
+ if (chat.welcomeColor)
21719
+ styles['--welcome-color'] = chat.welcomeColor;
21720
+ // Message bubbles
21721
+ if (chat.enableBubbles) {
21722
+ if (chat.bubbleUserColor)
21723
+ styles['--bubble-user-color'] = chat.bubbleUserColor;
21724
+ if (chat.bubbleUserOpacity !== undefined)
21725
+ styles['--bubble-user-opacity'] = chat.bubbleUserOpacity.toString();
21726
+ if (chat.bubbleAssistantColor)
21727
+ styles['--bubble-assistant-color'] = chat.bubbleAssistantColor;
21728
+ if (chat.bubbleAssistantOpacity !== undefined)
21729
+ styles['--bubble-assistant-opacity'] = chat.bubbleAssistantOpacity.toString();
21730
+ if (chat.bubbleBorderWidth !== undefined)
21731
+ styles['--bubble-border-width'] = `${chat.bubbleBorderWidth}px`;
21732
+ if (chat.bubbleBorderColor)
21733
+ styles['--bubble-border-color'] = chat.bubbleBorderColor;
21734
+ if (chat.bubbleBorderOpacity !== undefined)
21735
+ styles['--bubble-border-opacity'] = chat.bubbleBorderOpacity.toString();
21736
+ }
21737
+ else {
21738
+ // Plain text mode
21739
+ if (chat.textColor)
21740
+ styles['--message-text-color'] = chat.textColor;
21741
+ }
21742
+ // ========================================================================
21743
+ // FOOTER APPEARANCE
21744
+ // ========================================================================
21745
+ const footer = themeConfig.footer;
21746
+ // Only if separate from chat
21747
+ if (footer.separateFromChat) {
21748
+ if (footer.backgroundColor)
21749
+ styles['--footer-background'] = footer.backgroundColor;
21750
+ if (footer.opacity !== undefined)
21751
+ styles['--footer-opacity'] = footer.opacity.toString();
21752
+ if (footer.borderTopWidth !== undefined)
21753
+ styles['--footer-border-top-width'] = `${footer.borderTopWidth}px`;
21754
+ if (footer.borderTopColor)
21755
+ styles['--footer-border-top-color'] = footer.borderTopColor;
21756
+ if (footer.borderTopOpacity !== undefined)
21757
+ styles['--footer-border-top-opacity'] = footer.borderTopOpacity.toString();
21758
+ }
21759
+ // Backdrop blur (only when floating)
21760
+ if (!footer.separateFromChat && footer.backdropBlur !== undefined) {
21761
+ styles['--footer-backdrop-blur'] = `${footer.backdropBlur}px`;
21762
+ }
21763
+ // Input field
21764
+ if (footer.inputBackgroundColor)
21765
+ styles['--input-background'] = footer.inputBackgroundColor;
21766
+ if (footer.inputBackgroundOpacity !== undefined)
21767
+ styles['--input-background-opacity'] = footer.inputBackgroundOpacity.toString();
21768
+ if (footer.inputBorderRadius !== undefined)
21769
+ styles['--input-border-radius'] = `${footer.inputBorderRadius}px`;
21770
+ if (footer.inputBorderWidth !== undefined)
21771
+ styles['--input-border-width'] = `${footer.inputBorderWidth}px`;
21772
+ if (footer.inputBorderColor)
21773
+ styles['--input-border-color'] = footer.inputBorderColor;
21774
+ if (footer.inputBorderOpacity !== undefined)
21775
+ styles['--input-border-opacity'] = footer.inputBorderOpacity.toString();
21776
+ if (footer.inputShadow)
21777
+ styles['--input-shadow'] = getShadowValue(footer.inputShadow);
21778
+ // Send button
21779
+ if (footer.buttonBackgroundColor)
21780
+ styles['--send-button-background'] = footer.buttonBackgroundColor;
21781
+ if (footer.buttonOpacity !== undefined)
21782
+ styles['--send-button-opacity'] = footer.buttonOpacity.toString();
21783
+ if (footer.buttonBorderRadius !== undefined)
21784
+ styles['--send-button-border-radius'] = `${footer.buttonBorderRadius}px`;
21785
+ if (footer.buttonBorderWidth !== undefined)
21786
+ styles['--send-button-border-width'] = `${footer.buttonBorderWidth}px`;
21787
+ if (footer.buttonBorderColor)
21788
+ styles['--send-button-border-color'] = footer.buttonBorderColor;
21789
+ if (footer.buttonBorderOpacity !== undefined)
21790
+ styles['--send-button-border-opacity'] = footer.buttonBorderOpacity.toString();
21791
+ // ========================================================================
21792
+ // HOVER STATES
21793
+ // ========================================================================
21794
+ const hover = themeConfig.hover;
21795
+ if (hover.buttonScale !== undefined)
21796
+ styles['--hover-button-scale'] = hover.buttonScale.toString();
21797
+ if (hover.buttonOpacity !== undefined)
21798
+ styles['--hover-button-opacity'] = hover.buttonOpacity.toString();
21799
+ if (hover.inputBorderColor)
21800
+ styles['--hover-input-border-color'] = hover.inputBorderColor;
21801
+ if (hover.sendButtonOpacity !== undefined)
21802
+ styles['--hover-send-button-opacity'] = hover.sendButtonOpacity.toString();
21803
+ if (hover.closeButtonOpacity !== undefined)
21804
+ styles['--hover-close-button-opacity'] = hover.closeButtonOpacity.toString();
21805
+ // ========================================================================
21806
+ // ACTIVE STATES
21807
+ // ========================================================================
21808
+ const active = themeConfig.active;
21809
+ if (active.inputBorderColor)
21810
+ styles['--active-input-border-color'] = active.inputBorderColor;
21811
+ if (active.inputShadow)
21812
+ styles['--active-input-shadow'] = active.inputShadow;
21813
+ }
21814
+ else {
21815
+ // Fallback to legacy fields if no theme config
21816
+ if (appearance.primaryColor)
21817
+ styles['--primary-color'] = appearance.primaryColor;
21818
+ if (appearance.borderRadius !== undefined)
21819
+ styles['--border-radius'] = `${appearance.borderRadius}px`;
21820
+ // Legacy button
21821
+ if (appearance.button) {
21822
+ const btn = appearance.button;
21823
+ if (btn.color)
21824
+ styles['--button-color'] = btn.color;
21825
+ if (btn.size)
21826
+ styles['--button-size'] = `${btn.size}px`;
21827
+ if (btn.borderRadius !== undefined)
21828
+ styles['--button-border-radius'] = `${btn.borderRadius}px`;
21829
+ if (btn.borderWidth !== undefined)
21830
+ styles['--button-border-width'] = `${btn.borderWidth}px`;
21831
+ if (btn.borderColor)
21832
+ styles['--button-border-color'] = btn.borderColor;
21833
+ if (btn.opacity !== undefined)
21834
+ styles['--button-opacity'] = btn.opacity.toString();
21835
+ }
21836
+ }
21837
+ return styles;
21838
+ }
21839
+
21581
21840
  function styleInject(css, ref) {
21582
21841
  if ( ref === void 0 ) ref = {};
21583
21842
  var insertAt = ref.insertAt;
@@ -21605,11 +21864,26 @@ function styleInject(css, ref) {
21605
21864
  }
21606
21865
  }
21607
21866
 
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)}}";
21867
+ 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
21868
  styleInject(css_248z);
21610
21869
 
21870
+ // Icon components mapping
21871
+ const iconComponents = {
21872
+ FiMessageCircle: () => (jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: 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" }) })),
21873
+ FiMessageSquare: () => (jsx("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" }) })),
21874
+ FiMail: () => (jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [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" }), jsx("polyline", { points: "22,6 12,13 2,6" })] })),
21875
+ FiPhone: () => (jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: 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" }) })),
21876
+ FiHelpCircle: () => (jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsx("circle", { cx: "12", cy: "12", r: "10" }), jsx("path", { d: "M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3" }), jsx("line", { x1: "12", y1: "17", x2: "12.01", y2: "17" })] })),
21877
+ FiZap: () => (jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: jsx("polygon", { points: "13 2 3 14 12 14 11 22 21 10 12 10 13 2" }) })),
21878
+ FiSend: () => (jsxs("svg", { 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" })] })),
21879
+ FiUser: () => (jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsx("path", { d: "M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2" }), jsx("circle", { cx: "12", cy: "7", r: "4" })] })),
21880
+ FiUsers: () => (jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsx("path", { d: "M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2" }), jsx("circle", { cx: "9", cy: "7", r: "4" }), jsx("path", { d: "M23 21v-2a4 4 0 0 0-3-3.87" }), jsx("path", { d: "M16 3.13a4 4 0 0 1 0 7.75" })] })),
21881
+ FiHeadphones: () => (jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsx("path", { d: "M3 18v-6a9 9 0 0 1 18 0v6" }), 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" })] })),
21882
+ FiCpu: () => (jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsx("rect", { x: "4", y: "4", width: "16", height: "16", rx: "2", ry: "2" }), jsx("rect", { x: "9", y: "9", width: "6", height: "6" }), jsx("line", { x1: "9", y1: "1", x2: "9", y2: "4" }), jsx("line", { x1: "15", y1: "1", x2: "15", y2: "4" }), jsx("line", { x1: "9", y1: "20", x2: "9", y2: "23" }), jsx("line", { x1: "15", y1: "20", x2: "15", y2: "23" }), jsx("line", { x1: "20", y1: "9", x2: "23", y2: "9" }), jsx("line", { x1: "20", y1: "14", x2: "23", y2: "14" }), jsx("line", { x1: "1", y1: "9", x2: "4", y2: "9" }), jsx("line", { x1: "1", y1: "14", x2: "4", y2: "14" })] })),
21883
+ };
21611
21884
  const ChatWidget = ({ widgetId, apiKey, apiUrl = window.location.origin, position = 'bottom-right', theme: themeOverride, primaryColor, onOpen, onClose, onMessage, onError, }) => {
21612
21885
  const [isOpen, setIsOpen] = useState(false);
21886
+ const widgetRef = useRef(null);
21613
21887
  const { messages, isLoading, isTyping, error, config, sendMessage, submitFeedback, } = useChat({
21614
21888
  widgetId,
21615
21889
  apiKey,
@@ -21617,6 +21891,21 @@ const ChatWidget = ({ widgetId, apiKey, apiUrl = window.location.origin, positio
21617
21891
  onMessage,
21618
21892
  onError,
21619
21893
  });
21894
+ // Debug logging
21895
+ useEffect(() => {
21896
+ console.log('[ChatWidget] Config loaded:', config ? 'YES' : 'NO');
21897
+ if (config) {
21898
+ console.log('[ChatWidget] Config details:', {
21899
+ theme: config.appearance?.theme,
21900
+ darkModeEnabled: config.appearance?.darkModeEnabled,
21901
+ hasLightMode: !!config.appearance?.lightMode,
21902
+ hasDarkMode: !!config.appearance?.darkMode,
21903
+ });
21904
+ }
21905
+ }, [config]);
21906
+ useEffect(() => {
21907
+ console.log('[ChatWidget] isOpen changed:', isOpen);
21908
+ }, [isOpen]);
21620
21909
  // Handle auto-open
21621
21910
  useEffect(() => {
21622
21911
  if (config?.behavior.autoOpen) {
@@ -21629,26 +21918,84 @@ const ChatWidget = ({ widgetId, apiKey, apiUrl = window.location.origin, positio
21629
21918
  }
21630
21919
  return undefined;
21631
21920
  }, [config, onOpen]);
21921
+ // Handle close on outside click
21922
+ useEffect(() => {
21923
+ if (!isOpen || !config?.appearance.closeOnOutsideClick)
21924
+ return;
21925
+ const handleClickOutside = (event) => {
21926
+ if (widgetRef.current && !widgetRef.current.contains(event.target)) {
21927
+ console.log('[ChatWidget] Closing due to outside click');
21928
+ setIsOpen(false);
21929
+ onClose?.();
21930
+ }
21931
+ };
21932
+ // Add slight delay to avoid immediate close on open
21933
+ const timer = setTimeout(() => {
21934
+ document.addEventListener('mousedown', handleClickOutside);
21935
+ }, 100);
21936
+ return () => {
21937
+ clearTimeout(timer);
21938
+ document.removeEventListener('mousedown', handleClickOutside);
21939
+ };
21940
+ }, [isOpen, config, onClose]);
21941
+ // Handle close on Escape key
21942
+ useEffect(() => {
21943
+ if (!isOpen || !config?.appearance.closeOnEscape)
21944
+ return;
21945
+ const handleEscapeKey = (event) => {
21946
+ if (event.key === 'Escape') {
21947
+ setIsOpen(false);
21948
+ onClose?.();
21949
+ }
21950
+ };
21951
+ document.addEventListener('keydown', handleEscapeKey);
21952
+ return () => document.removeEventListener('keydown', handleEscapeKey);
21953
+ }, [isOpen, config, onClose]);
21632
21954
  // Determine theme
21633
- const theme = themeOverride || config?.appearance.theme || 'light';
21634
- const effectiveTheme = theme === 'auto'
21635
- ? (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light')
21636
- : theme;
21955
+ const appearanceConfig = config?.appearance;
21956
+ const themeSetting = themeOverride || appearanceConfig?.theme || 'light';
21957
+ const canUseDarkMode = appearanceConfig?.darkModeEnabled !== false;
21958
+ // Only check system preference if dark mode is enabled
21959
+ const systemPrefersDark = canUseDarkMode && typeof window !== "undefined"
21960
+ ? window.matchMedia('(prefers-color-scheme: dark)').matches
21961
+ : false;
21962
+ const effectiveTheme = !canUseDarkMode
21963
+ ? 'light' // Force light mode if dark mode is disabled
21964
+ : themeSetting === 'auto'
21965
+ ? (systemPrefersDark ? 'dark' : 'light')
21966
+ : themeSetting === 'dark'
21967
+ ? 'dark'
21968
+ : 'light';
21637
21969
  // Determine position (config takes priority over prop)
21638
21970
  const effectivePosition = config?.appearance.position || position;
21639
- // Apply custom styles
21640
- const customStyles = {};
21641
- if (primaryColor || config?.appearance.primaryColor) {
21642
- customStyles['--primary-color'] = primaryColor || config?.appearance.primaryColor || '';
21643
- }
21644
- if (config?.appearance.fontFamily) {
21645
- customStyles.fontFamily = config.appearance.fontFamily;
21646
- }
21647
- if (config?.appearance.borderRadius !== undefined) {
21648
- customStyles['--border-radius'] = `${config.appearance.borderRadius}px`;
21649
- }
21971
+ // Apply custom styles from appearance configuration
21972
+ // Use the correct theme configuration (lightMode or darkMode)
21973
+ const customStyles = appearanceConfig
21974
+ ? applyAppearanceStyles(appearanceConfig, effectiveTheme)
21975
+ : {};
21976
+ // Override with prop values if provided
21977
+ if (primaryColor) {
21978
+ customStyles['--primary-color'] = primaryColor;
21979
+ }
21980
+ // Debug logging for theme and styles
21981
+ useEffect(() => {
21982
+ console.log('[ChatWidget] Theme info:', {
21983
+ effectiveTheme,
21984
+ canUseDarkMode,
21985
+ themeSetting,
21986
+ systemPrefersDark,
21987
+ hasCustomStyles: Object.keys(customStyles).length > 0,
21988
+ buttonColor: customStyles['--button-color'],
21989
+ buttonSize: customStyles['--button-size'],
21990
+ cardBackground: customStyles['--card-background'],
21991
+ cardOpacity: customStyles['--card-opacity'],
21992
+ cardBorderRadius: customStyles['--card-border-radius'],
21993
+ });
21994
+ console.log('[ChatWidget] All CSS variables:', customStyles);
21995
+ }, [effectiveTheme, customStyles]);
21650
21996
  const handleToggle = () => {
21651
21997
  const newState = !isOpen;
21998
+ console.log('[ChatWidget] handleToggle called, setting isOpen to:', newState);
21652
21999
  setIsOpen(newState);
21653
22000
  if (newState) {
21654
22001
  onOpen?.();
@@ -21660,10 +22007,22 @@ const ChatWidget = ({ widgetId, apiKey, apiUrl = window.location.origin, positio
21660
22007
  const handleFeedback = async (messageId, feedback) => {
21661
22008
  await submitFeedback(messageId, feedback);
21662
22009
  };
21663
- return (jsx("div", { className: `ai-chat-widget ${effectiveTheme}`, style: customStyles, children: jsx("div", { 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 })) : (jsx("button", { className: "ai-chat-button", onClick: handleToggle, "aria-label": "Open chat", style: {
21664
- width: config?.appearance.buttonSize || 60,
21665
- height: config?.appearance.buttonSize || 60,
21666
- }, 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" }) })) })) }) }));
22010
+ // Don't render until config is loaded to avoid flash of unstyled content
22011
+ if (!config) {
22012
+ console.log('[ChatWidget] Not rendering - config not loaded yet');
22013
+ return null;
22014
+ }
22015
+ console.log('[ChatWidget] Rendering widget', { isOpen, hasConfig: !!config });
22016
+ 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 && (() => {
22017
+ // Get icon from theme config
22018
+ const themeConfig = effectiveTheme === 'dark'
22019
+ ? appearanceConfig?.darkMode
22020
+ : appearanceConfig?.lightMode;
22021
+ const buttonIcon = themeConfig?.button?.icon || 'FiMessageCircle';
22022
+ const buttonIconColor = themeConfig?.button?.iconColor || customStyles['--button-icon-color'] || '#ffffff';
22023
+ const IconComponent = iconComponents[buttonIcon] || iconComponents.FiMessageCircle;
22024
+ return (jsx("button", { className: "ai-chat-button", onClick: handleToggle, "aria-label": "Open chat", style: { color: buttonIconColor }, children: jsx("div", { className: "ai-chat-button-svg", children: jsx(IconComponent, {}) }) }));
22025
+ })()] }) }));
21667
22026
  };
21668
22027
 
21669
22028
  export { ApiError, ChatWidget, useChat };