@chatwidgetai/chat-widget 0.1.6 → 0.1.7

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.
@@ -17755,8 +17755,6 @@
17755
17755
  const config = await apiClient.current.getConfig();
17756
17756
  console.log('[useChat] Config fetched successfully:', {
17757
17757
  hasAppearance: !!config.appearance,
17758
- hasLightMode: !!config.appearance?.lightMode,
17759
- hasDarkMode: !!config.appearance?.darkMode,
17760
17758
  });
17761
17759
  const persistConversation = config.behavior.persistConversation ?? true;
17762
17760
  let conversationId = '';
@@ -38912,20 +38910,17 @@
38912
38910
  console.log('[ChatWindow] Rendering ChatWindow component');
38913
38911
  const appearance = config?.appearance;
38914
38912
  const behavior = config?.behavior;
38913
+ // Use simplified appearance fields
38915
38914
  const size = appearance?.size || 'medium';
38916
- console.log('[ChatWindow] Size:', size, 'Appearance:', !!appearance);
38917
- // Determine current theme config
38918
- const themePreference = appearance?.theme ?? 'light';
38919
- const canUseDarkMode = appearance?.darkModeEnabled !== false;
38920
- const prefersDark = typeof window !== 'undefined' && window.matchMedia('(prefers-color-scheme: dark)').matches;
38921
- const isDarkMode = themePreference === 'auto'
38922
- ? (canUseDarkMode && prefersDark)
38923
- : themePreference === 'dark' && canUseDarkMode;
38924
- const themeConfig = (isDarkMode ? appearance?.darkMode : appearance?.lightMode) ?? (appearance?.lightMode || appearance?.darkMode);
38925
- const headerTitle = themeConfig?.header?.title ?? appearance?.header?.title ?? appearance?.companyName ?? 'AI Assistant';
38926
- const welcomeTitle = themeConfig?.chat?.welcomeTitle ?? 'Welcome!';
38927
- const welcomeMessage = themeConfig?.chat?.welcomeMessage ?? appearance?.welcomeMessage ?? '👋 Hi there! How can I assist you today?';
38928
- const inputPlaceholder = themeConfig?.footer?.inputPlaceholder ?? appearance?.placeholder ?? 'Ask me anything...';
38915
+ const headerTitle = appearance?.headerTitle || 'AI Assistant';
38916
+ const welcomeMessage = appearance?.welcomeMessage || '👋 Hi there! How can I assist you today?';
38917
+ const inputPlaceholder = appearance?.placeholder || 'Ask me anything...';
38918
+ console.log('[ChatWindow] Appearance values:', {
38919
+ size,
38920
+ headerTitle,
38921
+ welcomeMessage,
38922
+ inputPlaceholder,
38923
+ });
38929
38924
  // Track if suggested questions should be shown
38930
38925
  const [showSuggestedQuestions, setShowSuggestedQuestions] = reactExports.useState(true);
38931
38926
  // Hide suggested questions after first user message
@@ -38945,241 +38940,25 @@
38945
38940
  onSendMessage(question);
38946
38941
  };
38947
38942
  const hasMessages = messages.length > 0;
38948
- return (jsxRuntimeExports.jsxs("div", { className: `ai-chat-window size-${size}`, role: "dialog", "aria-label": "Chat window", children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-header", children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-header-content", children: [appearance?.logo && (jsxRuntimeExports.jsx("img", { src: appearance.logo, alt: "Logo", className: "ai-chat-logo" })), jsxRuntimeExports.jsx("div", { className: "ai-chat-title", children: headerTitle })] }), jsxRuntimeExports.jsx("button", { className: "ai-chat-close-button", onClick: onClose, "aria-label": "Minimize chat", children: jsxRuntimeExports.jsx(MinimizeIcon, {}) })] }), error && (jsxRuntimeExports.jsx("div", { className: "ai-chat-error", role: "alert", children: error })), maxMessages && userMessageCount >= maxMessages - 2 && !isLimitReached && (jsxRuntimeExports.jsxs("div", { className: "ai-chat-warning", role: "alert", children: [maxMessages - userMessageCount, " message", maxMessages - userMessageCount !== 1 ? 's' : '', " remaining"] })), isLimitReached && (jsxRuntimeExports.jsx("div", { className: "ai-chat-error", role: "alert", children: "Message limit reached. Please start a new conversation." })), jsxRuntimeExports.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 && !hasMessages && behavior?.suggestedQuestions && behavior.suggestedQuestions.length > 0 && (jsxRuntimeExports.jsx(SuggestedQuestions, { questions: behavior.suggestedQuestions, onQuestionClick: handleQuestionClick })), jsxRuntimeExports.jsx(MessageInput, { onSend: onSendMessage, placeholder: isLimitReached ? 'Message limit reached' : inputPlaceholder, disabled: isLoading || isLimitReached, enableFileUpload: behavior?.enableFileUpload, separateFromChat: themeConfig?.footer?.separateFromChat })] }));
38943
+ return (jsxRuntimeExports.jsxs("div", { className: `ai-chat-window size-${size}`, role: "dialog", "aria-label": "Chat window", children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-header", children: [jsxRuntimeExports.jsxs("div", { className: "ai-chat-header-content", children: [appearance?.logo && (jsxRuntimeExports.jsx("img", { src: appearance.logo, alt: "Logo", className: "ai-chat-logo" })), jsxRuntimeExports.jsx("div", { className: "ai-chat-title", children: headerTitle })] }), jsxRuntimeExports.jsx("button", { className: "ai-chat-close-button", onClick: onClose, "aria-label": "Minimize chat", children: jsxRuntimeExports.jsx(MinimizeIcon, {}) })] }), error && (jsxRuntimeExports.jsx("div", { className: "ai-chat-error", role: "alert", children: error })), maxMessages && userMessageCount >= maxMessages - 2 && !isLimitReached && (jsxRuntimeExports.jsxs("div", { className: "ai-chat-warning", role: "alert", children: [maxMessages - userMessageCount, " message", maxMessages - userMessageCount !== 1 ? 's' : '', " remaining"] })), isLimitReached && (jsxRuntimeExports.jsx("div", { className: "ai-chat-error", role: "alert", children: "Message limit reached. Please start a new conversation." })), jsxRuntimeExports.jsx(MessageList, { messages: messages, isTyping: isTyping, showTypingIndicator: behavior?.showTypingIndicator, showTimestamps: behavior?.showTimestamps, enableFeedback: behavior?.enableFeedback, showSources: behavior?.showSources, sourceDisplayMode: behavior?.sourceDisplayMode, welcomeMessage: welcomeMessage, onFeedback: onFeedback }), showSuggestedQuestions && !hasMessages && behavior?.suggestedQuestions && behavior.suggestedQuestions.length > 0 && (jsxRuntimeExports.jsx(SuggestedQuestions, { questions: behavior.suggestedQuestions, onQuestionClick: handleQuestionClick })), jsxRuntimeExports.jsx(MessageInput, { onSend: onSendMessage, placeholder: isLimitReached ? 'Message limit reached' : inputPlaceholder, disabled: isLoading || isLimitReached, enableFileUpload: behavior?.enableFileUpload })] }));
38949
38944
  };
38950
38945
 
38951
- /**
38952
- * Convert shadow size to CSS box-shadow value
38953
- */
38954
- function getShadowValue(size) {
38955
- const shadows = {
38956
- 'none': 'none',
38957
- 'sm': '0 1px 2px 0 rgba(0, 0, 0, 0.05)',
38958
- 'md': '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)',
38959
- 'lg': '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)',
38960
- 'xl': '0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)',
38961
- '2xl': '0 25px 50px -12px rgba(0, 0, 0, 0.25)',
38962
- };
38963
- return shadows[size] || shadows.none;
38964
- }
38965
38946
  /**
38966
38947
  * Apply appearance configuration as CSS custom properties
38967
- * This allows the widget to be fully customizable via the appearance config
38948
+ * Simplified to only handle flat appearance schema
38968
38949
  *
38969
38950
  * @param appearance - Widget appearance configuration
38970
- * @param theme - Current theme ('light' or 'dark')
38951
+ * @param theme - Current theme ('light' or 'dark') - kept for compatibility but not used for theme selection
38971
38952
  */
38972
- function applyAppearanceStyles(appearance, theme = 'light') {
38953
+ function applyAppearanceStyles(appearance) {
38973
38954
  const styles = {};
38974
- // Global font family
38975
- if (appearance.fontFamily) {
38976
- styles.fontFamily = appearance.fontFamily;
38977
- }
38978
- // Select the correct theme configuration
38979
- const themeConfig = theme === 'dark' ? appearance.darkMode : appearance.lightMode;
38980
- // If theme config exists and has required properties, use it
38981
- if (themeConfig && themeConfig.button) {
38982
- // ========================================================================
38983
- // BUTTON APPEARANCE
38984
- // ========================================================================
38985
- const btn = themeConfig.button;
38986
- if (btn.color)
38987
- styles['--button-color'] = btn.color;
38988
- if (btn.opacity !== undefined)
38989
- styles['--button-opacity'] = btn.opacity.toString();
38990
- if (btn.size)
38991
- styles['--button-size'] = `${btn.size}px`;
38992
- if (btn.icon)
38993
- styles['--button-icon'] = btn.icon;
38994
- if (btn.iconColor)
38995
- styles['--button-icon-color'] = btn.iconColor;
38996
- if (btn.borderRadius !== undefined)
38997
- styles['--button-border-radius'] = `${btn.borderRadius}px`;
38998
- if (btn.borderWidth !== undefined)
38999
- styles['--button-border-width'] = `${btn.borderWidth}px`;
39000
- if (btn.borderColor)
39001
- styles['--button-border-color'] = btn.borderColor;
39002
- if (btn.borderOpacity !== undefined)
39003
- styles['--button-border-opacity'] = btn.borderOpacity.toString();
39004
- if (btn.backdropBlur !== undefined)
39005
- styles['--button-backdrop-blur'] = `${btn.backdropBlur}px`;
39006
- if (btn.shadow)
39007
- styles['--button-shadow'] = getShadowValue(btn.shadow);
39008
- // ========================================================================
39009
- // CARD/WINDOW APPEARANCE
39010
- // ========================================================================
39011
- const card = themeConfig.card;
39012
- if (card.backgroundColor)
39013
- styles['--card-background'] = card.backgroundColor;
39014
- if (card.opacity !== undefined)
39015
- styles['--card-opacity'] = card.opacity.toString();
39016
- if (card.borderRadius !== undefined)
39017
- styles['--card-border-radius'] = `${card.borderRadius}px`;
39018
- if (card.borderWidth !== undefined)
39019
- styles['--card-border-width'] = `${card.borderWidth}px`;
39020
- if (card.borderColor) {
39021
- styles['--card-border-color'] = card.borderColor;
39022
- // Create rgba border color with opacity for box-shadow
39023
- if (card.borderOpacity !== undefined) {
39024
- const opacity = card.borderOpacity;
39025
- // Convert hex to rgba
39026
- const hex = card.borderColor.replace('#', '');
39027
- const r = parseInt(hex.substring(0, 2), 16);
39028
- const g = parseInt(hex.substring(2, 4), 16);
39029
- const b = parseInt(hex.substring(4, 6), 16);
39030
- styles['--card-border-color-rgba'] = `rgba(${r}, ${g}, ${b}, ${opacity})`;
39031
- }
39032
- }
39033
- if (card.borderOpacity !== undefined)
39034
- styles['--card-border-opacity'] = card.borderOpacity.toString();
39035
- if (card.backdropBlur !== undefined)
39036
- styles['--card-backdrop-blur'] = `${card.backdropBlur}px`;
39037
- if (card.shadow)
39038
- styles['--card-shadow'] = getShadowValue(card.shadow);
39039
- // ========================================================================
39040
- // HEADER APPEARANCE
39041
- // ========================================================================
39042
- const header = themeConfig.header;
39043
- if (header.backgroundColor)
39044
- styles['--header-background'] = header.backgroundColor;
39045
- if (header.opacity !== undefined)
39046
- styles['--header-opacity'] = header.opacity.toString();
39047
- if (header.textColor)
39048
- styles['--header-text-color'] = header.textColor;
39049
- if (header.borderBottomWidth !== undefined)
39050
- styles['--header-border-bottom-width'] = `${header.borderBottomWidth}px`;
39051
- if (header.borderBottomColor)
39052
- styles['--header-border-bottom-color'] = header.borderBottomColor;
39053
- if (header.borderBottomOpacity !== undefined)
39054
- styles['--header-border-bottom-opacity'] = header.borderBottomOpacity.toString();
39055
- // ========================================================================
39056
- // CHAT APPEARANCE
39057
- // ========================================================================
39058
- const chat = themeConfig.chat;
39059
- if (chat.backgroundColor)
39060
- styles['--chat-background'] = chat.backgroundColor;
39061
- if (chat.opacity !== undefined)
39062
- styles['--chat-opacity'] = chat.opacity.toString();
39063
- // Welcome message
39064
- if (chat.welcomeColor)
39065
- styles['--welcome-color'] = chat.welcomeColor;
39066
- // Message bubbles
39067
- if (chat.enableBubbles) {
39068
- if (chat.bubbleUserColor)
39069
- styles['--bubble-user-color'] = chat.bubbleUserColor;
39070
- if (chat.bubbleUserOpacity !== undefined)
39071
- styles['--bubble-user-opacity'] = chat.bubbleUserOpacity.toString();
39072
- if (chat.bubbleAssistantColor)
39073
- styles['--bubble-assistant-color'] = chat.bubbleAssistantColor;
39074
- if (chat.bubbleAssistantOpacity !== undefined)
39075
- styles['--bubble-assistant-opacity'] = chat.bubbleAssistantOpacity.toString();
39076
- if (chat.bubbleBorderWidth !== undefined)
39077
- styles['--bubble-border-width'] = `${chat.bubbleBorderWidth}px`;
39078
- if (chat.bubbleBorderColor)
39079
- styles['--bubble-border-color'] = chat.bubbleBorderColor;
39080
- if (chat.bubbleBorderOpacity !== undefined)
39081
- styles['--bubble-border-opacity'] = chat.bubbleBorderOpacity.toString();
39082
- }
39083
- else {
39084
- // Plain text mode
39085
- if (chat.textColor)
39086
- styles['--message-text-color'] = chat.textColor;
39087
- }
39088
- // ========================================================================
39089
- // FOOTER APPEARANCE
39090
- // ========================================================================
39091
- const footer = themeConfig.footer;
39092
- // Only if separate from chat
39093
- if (footer.separateFromChat) {
39094
- if (footer.backgroundColor)
39095
- styles['--footer-background'] = footer.backgroundColor;
39096
- if (footer.opacity !== undefined)
39097
- styles['--footer-opacity'] = footer.opacity.toString();
39098
- if (footer.borderTopWidth !== undefined)
39099
- styles['--footer-border-top-width'] = `${footer.borderTopWidth}px`;
39100
- if (footer.borderTopColor)
39101
- styles['--footer-border-top-color'] = footer.borderTopColor;
39102
- if (footer.borderTopOpacity !== undefined)
39103
- styles['--footer-border-top-opacity'] = footer.borderTopOpacity.toString();
39104
- }
39105
- // Backdrop blur (only when floating)
39106
- if (!footer.separateFromChat && footer.backdropBlur !== undefined) {
39107
- styles['--footer-backdrop-blur'] = `${footer.backdropBlur}px`;
39108
- }
39109
- // Input field
39110
- if (footer.inputBackgroundColor)
39111
- styles['--input-background'] = footer.inputBackgroundColor;
39112
- if (footer.inputBackgroundOpacity !== undefined)
39113
- styles['--input-background-opacity'] = footer.inputBackgroundOpacity.toString();
39114
- if (footer.inputBorderRadius !== undefined)
39115
- styles['--input-border-radius'] = `${footer.inputBorderRadius}px`;
39116
- if (footer.inputBorderWidth !== undefined)
39117
- styles['--input-border-width'] = `${footer.inputBorderWidth}px`;
39118
- if (footer.inputBorderColor)
39119
- styles['--input-border-color'] = footer.inputBorderColor;
39120
- if (footer.inputBorderOpacity !== undefined)
39121
- styles['--input-border-opacity'] = footer.inputBorderOpacity.toString();
39122
- if (footer.inputShadow)
39123
- styles['--input-shadow'] = getShadowValue(footer.inputShadow);
39124
- // Send button
39125
- if (footer.buttonBackgroundColor)
39126
- styles['--send-button-background'] = footer.buttonBackgroundColor;
39127
- if (footer.buttonOpacity !== undefined)
39128
- styles['--send-button-opacity'] = footer.buttonOpacity.toString();
39129
- if (footer.buttonBorderRadius !== undefined)
39130
- styles['--send-button-border-radius'] = `${footer.buttonBorderRadius}px`;
39131
- if (footer.buttonBorderWidth !== undefined)
39132
- styles['--send-button-border-width'] = `${footer.buttonBorderWidth}px`;
39133
- if (footer.buttonBorderColor)
39134
- styles['--send-button-border-color'] = footer.buttonBorderColor;
39135
- if (footer.buttonBorderOpacity !== undefined)
39136
- styles['--send-button-border-opacity'] = footer.buttonBorderOpacity.toString();
39137
- // ========================================================================
39138
- // HOVER STATES
39139
- // ========================================================================
39140
- const hover = themeConfig.hover;
39141
- if (hover.buttonScale !== undefined)
39142
- styles['--hover-button-scale'] = hover.buttonScale.toString();
39143
- if (hover.buttonOpacity !== undefined)
39144
- styles['--hover-button-opacity'] = hover.buttonOpacity.toString();
39145
- if (hover.inputBorderColor)
39146
- styles['--hover-input-border-color'] = hover.inputBorderColor;
39147
- if (hover.sendButtonOpacity !== undefined)
39148
- styles['--hover-send-button-opacity'] = hover.sendButtonOpacity.toString();
39149
- if (hover.closeButtonOpacity !== undefined)
39150
- styles['--hover-close-button-opacity'] = hover.closeButtonOpacity.toString();
39151
- // ========================================================================
39152
- // ACTIVE STATES
39153
- // ========================================================================
39154
- const active = themeConfig.active;
39155
- if (active.inputBorderColor)
39156
- styles['--active-input-border-color'] = active.inputBorderColor;
39157
- if (active.inputShadow)
39158
- styles['--active-input-shadow'] = active.inputShadow;
39159
- }
39160
- else {
39161
- // Fallback to legacy fields if no theme config
39162
- if (appearance.primaryColor)
39163
- styles['--primary-color'] = appearance.primaryColor;
39164
- if (appearance.borderRadius !== undefined)
39165
- styles['--border-radius'] = `${appearance.borderRadius}px`;
39166
- // Legacy button
39167
- if (appearance.button) {
39168
- const btn = appearance.button;
39169
- if (btn.color)
39170
- styles['--button-color'] = btn.color;
39171
- if (btn.size)
39172
- styles['--button-size'] = `${btn.size}px`;
39173
- if (btn.borderRadius !== undefined)
39174
- styles['--button-border-radius'] = `${btn.borderRadius}px`;
39175
- if (btn.borderWidth !== undefined)
39176
- styles['--button-border-width'] = `${btn.borderWidth}px`;
39177
- if (btn.borderColor)
39178
- styles['--button-border-color'] = btn.borderColor;
39179
- if (btn.opacity !== undefined)
39180
- styles['--button-opacity'] = btn.opacity.toString();
39181
- }
38955
+ // Apply primary color
38956
+ if (appearance.primaryColor) {
38957
+ styles['--primary-color'] = appearance.primaryColor;
39182
38958
  }
38959
+ // Note: All legacy theme system code (lightMode, darkMode, ThemeAppearanceConfig)
38960
+ // has been removed. The widget now uses a simplified flat appearance schema.
38961
+ // Theme-specific styling is handled by generateThemeStyles() using auto-detected theme.
39183
38962
  return styles;
39184
38963
  }
39185
38964
 
@@ -39541,19 +39320,23 @@
39541
39320
  * Create a MutationObserver to watch for theme changes
39542
39321
  */
39543
39322
  function createThemeObserver(element, callback) {
39323
+ let lastTheme = detectTheme(element);
39544
39324
  const observer = new MutationObserver(() => {
39545
39325
  const theme = detectTheme(element);
39546
- callback(theme);
39326
+ if (theme !== lastTheme) {
39327
+ lastTheme = theme;
39328
+ callback(theme);
39329
+ }
39547
39330
  });
39548
39331
  // Observe body for class/style changes (common for theme switching)
39549
39332
  observer.observe(document.body, {
39550
39333
  attributes: true,
39551
- attributeFilter: ['class', 'style', 'data-theme'],
39334
+ attributeFilter: ['class', 'style', 'data-theme', 'data-bs-theme'],
39552
39335
  });
39553
39336
  // Also observe html element
39554
39337
  observer.observe(document.documentElement, {
39555
39338
  attributes: true,
39556
- attributeFilter: ['class', 'style', 'data-theme'],
39339
+ attributeFilter: ['class', 'style', 'data-theme', 'data-bs-theme'],
39557
39340
  });
39558
39341
  return observer;
39559
39342
  }
@@ -39594,19 +39377,9 @@
39594
39377
  // Icon components mapping
39595
39378
  const iconComponents = {
39596
39379
  FiMessageCircle: () => (jsxRuntimeExports.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: jsxRuntimeExports.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" }) })),
39597
- FiMessageSquare: () => (jsxRuntimeExports.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: jsxRuntimeExports.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" }) })),
39598
- FiMail: () => (jsxRuntimeExports.jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntimeExports.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" }), jsxRuntimeExports.jsx("polyline", { points: "22,6 12,13 2,6" })] })),
39599
- FiPhone: () => (jsxRuntimeExports.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: jsxRuntimeExports.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" }) })),
39600
- FiHelpCircle: () => (jsxRuntimeExports.jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntimeExports.jsx("circle", { cx: "12", cy: "12", r: "10" }), jsxRuntimeExports.jsx("path", { d: "M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3" }), jsxRuntimeExports.jsx("line", { x1: "12", y1: "17", x2: "12.01", y2: "17" })] })),
39601
- FiZap: () => (jsxRuntimeExports.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: jsxRuntimeExports.jsx("polygon", { points: "13 2 3 14 12 14 11 22 21 10 12 10 13 2" }) })),
39602
- FiSend: () => (jsxRuntimeExports.jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntimeExports.jsx("line", { x1: "22", y1: "2", x2: "11", y2: "13" }), jsxRuntimeExports.jsx("polygon", { points: "22 2 15 22 11 13 2 9 22 2" })] })),
39603
- FiUser: () => (jsxRuntimeExports.jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntimeExports.jsx("path", { d: "M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2" }), jsxRuntimeExports.jsx("circle", { cx: "12", cy: "7", r: "4" })] })),
39604
- FiUsers: () => (jsxRuntimeExports.jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntimeExports.jsx("path", { d: "M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2" }), jsxRuntimeExports.jsx("circle", { cx: "9", cy: "7", r: "4" }), jsxRuntimeExports.jsx("path", { d: "M23 21v-2a4 4 0 0 0-3-3.87" }), jsxRuntimeExports.jsx("path", { d: "M16 3.13a4 4 0 0 1 0 7.75" })] })),
39605
- FiHeadphones: () => (jsxRuntimeExports.jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntimeExports.jsx("path", { d: "M3 18v-6a9 9 0 0 1 18 0v6" }), jsxRuntimeExports.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" })] })),
39606
- FiCpu: () => (jsxRuntimeExports.jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntimeExports.jsx("rect", { x: "4", y: "4", width: "16", height: "16", rx: "2", ry: "2" }), jsxRuntimeExports.jsx("rect", { x: "9", y: "9", width: "6", height: "6" }), jsxRuntimeExports.jsx("line", { x1: "9", y1: "1", x2: "9", y2: "4" }), jsxRuntimeExports.jsx("line", { x1: "15", y1: "1", x2: "15", y2: "4" }), jsxRuntimeExports.jsx("line", { x1: "9", y1: "20", x2: "9", y2: "23" }), jsxRuntimeExports.jsx("line", { x1: "15", y1: "20", x2: "15", y2: "23" }), jsxRuntimeExports.jsx("line", { x1: "20", y1: "9", x2: "23", y2: "9" }), jsxRuntimeExports.jsx("line", { x1: "20", y1: "14", x2: "23", y2: "14" }), jsxRuntimeExports.jsx("line", { x1: "1", y1: "9", x2: "4", y2: "9" }), jsxRuntimeExports.jsx("line", { x1: "1", y1: "14", x2: "4", y2: "14" })] })),
39607
39380
  FiChevronDown: () => (jsxRuntimeExports.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: jsxRuntimeExports.jsx("polyline", { points: "6 9 12 15 18 9" }) })),
39608
39381
  };
39609
- const ChatWidget = ({ widgetId, apiUrl = window.location.origin, position = 'bottom-right', theme: themeOverride, primaryColor, onOpen, onClose, onMessage, onError, }) => {
39382
+ const ChatWidget = ({ widgetId, apiUrl = window.location.origin, position = 'bottom-right', primaryColor, onOpen, onClose, onMessage, onError, }) => {
39610
39383
  const [isOpen, setIsOpen] = reactExports.useState(false);
39611
39384
  const [autoDetectedTheme, setAutoDetectedTheme] = reactExports.useState('light');
39612
39385
  const widgetRef = reactExports.useRef(null);
@@ -39647,7 +39420,6 @@
39647
39420
  console.log('[ChatWidget] Config loaded:', config ? 'YES' : 'NO');
39648
39421
  if (config) {
39649
39422
  console.log('[ChatWidget] Config details:', {
39650
- theme: config.appearance?.theme,
39651
39423
  accentColor: config.appearance?.primaryColor,
39652
39424
  autoDetectedTheme,
39653
39425
  });
@@ -39687,7 +39459,7 @@
39687
39459
  }, [isOpen, onClose]);
39688
39460
  // Handle close on Escape key
39689
39461
  reactExports.useEffect(() => {
39690
- if (!isOpen || !config?.appearance.closeOnEscape)
39462
+ if (!isOpen)
39691
39463
  return;
39692
39464
  const handleEscapeKey = (event) => {
39693
39465
  if (event.key === 'Escape') {
@@ -39697,16 +39469,10 @@
39697
39469
  };
39698
39470
  document.addEventListener('keydown', handleEscapeKey);
39699
39471
  return () => document.removeEventListener('keydown', handleEscapeKey);
39700
- }, [isOpen, config, onClose]);
39701
- // Determine theme - simplified: always auto-detect unless explicitly overridden
39472
+ }, [isOpen, onClose]);
39473
+ // Determine theme - always auto-detect from background
39702
39474
  const appearanceConfig = config?.appearance;
39703
- const themeSetting = themeOverride || appearanceConfig?.theme || 'auto';
39704
- // Use auto-detected theme, or explicit override
39705
- const effectiveTheme = themeSetting === 'auto'
39706
- ? autoDetectedTheme
39707
- : themeSetting === 'dark'
39708
- ? 'dark'
39709
- : 'light';
39475
+ const effectiveTheme = autoDetectedTheme;
39710
39476
  // Determine position (config takes priority over prop)
39711
39477
  const effectivePosition = config?.appearance.position || position;
39712
39478
  // Get accent color from config or prop
@@ -39715,17 +39481,15 @@
39715
39481
  const simpleAppearance = {
39716
39482
  accentColor,
39717
39483
  size: appearanceConfig?.size || 'small',
39718
- welcomeTitle: appearanceConfig?.lightMode?.chat?.welcomeTitle,
39719
- welcomeMessage: appearanceConfig?.welcomeMessage || appearanceConfig?.lightMode?.chat?.welcomeMessage,
39720
- placeholder: appearanceConfig?.placeholder || appearanceConfig?.lightMode?.footer?.inputPlaceholder,
39721
- headerTitle: appearanceConfig?.lightMode?.header?.title,
39722
- buttonIcon: appearanceConfig?.buttonIcon || appearanceConfig?.lightMode?.button?.icon,
39484
+ welcomeMessage: appearanceConfig?.welcomeMessage || '',
39485
+ placeholder: appearanceConfig?.placeholder || '',
39486
+ headerTitle: appearanceConfig?.headerTitle || '',
39723
39487
  };
39724
39488
  // Generate theme styles from accent color
39725
39489
  const generatedStyles = generateThemeStyles(simpleAppearance, effectiveTheme);
39726
39490
  // Also apply legacy styles for backward compatibility
39727
39491
  const legacyStyles = appearanceConfig
39728
- ? applyAppearanceStyles(appearanceConfig, effectiveTheme)
39492
+ ? applyAppearanceStyles(appearanceConfig)
39729
39493
  : {};
39730
39494
  // Merge styles (generated takes priority for new simplified system)
39731
39495
  const customStyles = {
@@ -39737,10 +39501,9 @@
39737
39501
  console.log('[ChatWidget] Theme info:', {
39738
39502
  effectiveTheme,
39739
39503
  autoDetectedTheme,
39740
- themeSetting,
39741
39504
  accentColor,
39742
39505
  });
39743
- }, [effectiveTheme, autoDetectedTheme, themeSetting, accentColor]);
39506
+ }, [effectiveTheme, autoDetectedTheme, accentColor]);
39744
39507
  const handleToggle = () => {
39745
39508
  const newState = !isOpen;
39746
39509
  console.log('[ChatWidget] handleToggle called, setting isOpen to:', newState);
@@ -39762,24 +39525,8 @@
39762
39525
  }
39763
39526
  console.log('[ChatWidget] Rendering widget', { isOpen, hasConfig: !!config });
39764
39527
  // Get button icon based on state
39765
- const getButtonIcon = () => {
39766
- if (isOpen) {
39767
- return iconComponents.FiChevronDown;
39768
- }
39769
- const themeConfig = effectiveTheme === 'dark'
39770
- ? appearanceConfig?.darkMode
39771
- : appearanceConfig?.lightMode;
39772
- const buttonIcon = themeConfig?.button?.icon || 'FiMessageCircle';
39773
- return iconComponents[buttonIcon] || iconComponents.FiMessageCircle;
39774
- };
39775
- const buttonIconColor = (() => {
39776
- const themeConfig = effectiveTheme === 'dark'
39777
- ? appearanceConfig?.darkMode
39778
- : appearanceConfig?.lightMode;
39779
- return themeConfig?.button?.iconColor || customStyles['--button-icon-color'] || '#ffffff';
39780
- })();
39781
- const IconComponent = getButtonIcon();
39782
- return (jsxRuntimeExports.jsx("div", { ref: containerRef, className: `ai-chat-widget ${effectiveTheme}`, style: customStyles, children: jsxRuntimeExports.jsxs("div", { ref: widgetRef, className: `ai-chat-widget-container ${effectivePosition}`, children: [isOpen && (jsxRuntimeExports.jsx(ChatWindow, { messages: messages, isLoading: isLoading, isTyping: isTyping, error: error, config: config, onSendMessage: sendMessage, onClose: handleToggle, onFeedback: handleFeedback })), jsxRuntimeExports.jsx("button", { className: `ai-chat-button ${isOpen ? 'is-open' : ''}`, onClick: handleToggle, "aria-label": isOpen ? "Minimize chat" : "Open chat", style: { color: buttonIconColor }, children: jsxRuntimeExports.jsx("div", { className: "ai-chat-button-svg", children: jsxRuntimeExports.jsx(IconComponent, {}) }) })] }) }));
39528
+ const IconComponent = isOpen ? iconComponents.FiChevronDown : iconComponents.FiMessageCircle;
39529
+ return (jsxRuntimeExports.jsx("div", { ref: containerRef, className: `ai-chat-widget ${effectiveTheme}`, style: customStyles, children: jsxRuntimeExports.jsxs("div", { ref: widgetRef, className: `ai-chat-widget-container ${effectivePosition}`, children: [isOpen && (jsxRuntimeExports.jsx(ChatWindow, { messages: messages, isLoading: isLoading, isTyping: isTyping, error: error, config: config, onSendMessage: sendMessage, onClose: handleToggle, onFeedback: handleFeedback })), jsxRuntimeExports.jsx("button", { className: `ai-chat-button ${isOpen ? 'is-open' : ''}`, onClick: handleToggle, "aria-label": isOpen ? "Minimize chat" : "Open chat", children: jsxRuntimeExports.jsx("div", { className: "ai-chat-button-svg", children: jsxRuntimeExports.jsx(IconComponent, {}) }) })] }) }));
39783
39530
  };
39784
39531
 
39785
39532
  /**
@@ -39807,7 +39554,6 @@
39807
39554
  widgetId: options.widgetId,
39808
39555
  apiUrl: options.apiUrl,
39809
39556
  position: options.position,
39810
- theme: options.theme,
39811
39557
  primaryColor: options.primaryColor,
39812
39558
  onOpen: options.onOpen,
39813
39559
  onClose: options.onClose,