vanilla-agent 1.23.0 → 1.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -33,3 +33,5 @@ export function generateAssistantMessageId(): string {
33
33
  return `ast_${timestamp}_${random}`;
34
34
  }
35
35
 
36
+
37
+
@@ -1,10 +1,94 @@
1
- import { AgentWidgetConfig } from "../types";
1
+ import { AgentWidgetConfig, AgentWidgetTheme } from "../types";
2
+
3
+ /**
4
+ * Detects the current color scheme from the page.
5
+ * 1. Checks if <html> element has 'dark' class
6
+ * 2. Falls back to prefers-color-scheme media query
7
+ */
8
+ export const detectColorScheme = (): 'light' | 'dark' => {
9
+ // Check for 'dark' class on <html> element
10
+ if (typeof document !== 'undefined' && document.documentElement.classList.contains('dark')) {
11
+ return 'dark';
12
+ }
13
+
14
+ // Fall back to media query
15
+ if (typeof window !== 'undefined' && window.matchMedia?.('(prefers-color-scheme: dark)').matches) {
16
+ return 'dark';
17
+ }
18
+
19
+ return 'light';
20
+ };
21
+
22
+ /**
23
+ * Gets the active theme based on colorScheme setting and current detection.
24
+ */
25
+ export const getActiveTheme = (config?: AgentWidgetConfig): AgentWidgetTheme => {
26
+ const colorScheme = config?.colorScheme ?? 'light';
27
+ const lightTheme = config?.theme ?? {};
28
+ const darkTheme = config?.darkTheme ?? lightTheme;
29
+
30
+ if (colorScheme === 'light') {
31
+ return lightTheme;
32
+ }
33
+
34
+ if (colorScheme === 'dark') {
35
+ return darkTheme;
36
+ }
37
+
38
+ // colorScheme === 'auto'
39
+ const detectedScheme = detectColorScheme();
40
+ return detectedScheme === 'dark' ? darkTheme : lightTheme;
41
+ };
42
+
43
+ /**
44
+ * Creates observers for theme changes (HTML class and media query).
45
+ * Returns a cleanup function.
46
+ */
47
+ export const createThemeObserver = (
48
+ callback: (scheme: 'light' | 'dark') => void
49
+ ): (() => void) => {
50
+ const cleanupFns: Array<() => void> = [];
51
+
52
+ // Observe HTML class changes
53
+ if (typeof document !== 'undefined' && typeof MutationObserver !== 'undefined') {
54
+ const observer = new MutationObserver(() => {
55
+ callback(detectColorScheme());
56
+ });
57
+
58
+ observer.observe(document.documentElement, {
59
+ attributes: true,
60
+ attributeFilter: ['class']
61
+ });
62
+
63
+ cleanupFns.push(() => observer.disconnect());
64
+ }
65
+
66
+ // Observe media query changes
67
+ if (typeof window !== 'undefined' && window.matchMedia) {
68
+ const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
69
+ const handleChange = () => callback(detectColorScheme());
70
+
71
+ // Use addEventListener if available (modern browsers), otherwise addListener
72
+ if (mediaQuery.addEventListener) {
73
+ mediaQuery.addEventListener('change', handleChange);
74
+ cleanupFns.push(() => mediaQuery.removeEventListener('change', handleChange));
75
+ } else if (mediaQuery.addListener) {
76
+ // Legacy Safari
77
+ mediaQuery.addListener(handleChange);
78
+ cleanupFns.push(() => mediaQuery.removeListener(handleChange));
79
+ }
80
+ }
81
+
82
+ return () => {
83
+ cleanupFns.forEach(fn => fn());
84
+ };
85
+ };
2
86
 
3
87
  export const applyThemeVariables = (
4
88
  element: HTMLElement,
5
89
  config?: AgentWidgetConfig
6
90
  ) => {
7
- const theme = config?.theme ?? {};
91
+ const theme = getActiveTheme(config);
8
92
  Object.entries(theme).forEach(([key, value]) => {
9
93
  // Skip undefined or empty values
10
94
  if (value === undefined || value === null || value === "") {
@@ -19,7 +103,3 @@ export const applyThemeVariables = (
19
103
 
20
104
 
21
105
 
22
-
23
-
24
-
25
-