@lastbrain/ai-ui-react 1.0.9 → 1.0.11

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.
@@ -24,8 +24,8 @@ const colors = {
24
24
  bg: "#ffffff",
25
25
  bgSecondary: "#f9fafb",
26
26
  bgTertiary: "#f3f4f6",
27
- border: "#e5e7eb",
28
- borderLight: "#f3f4f6",
27
+ border: "#e2e8f0",
28
+ borderLight: "#f1f5f9",
29
29
  text: "#111827",
30
30
  textSecondary: "#6b7280",
31
31
  textTertiary: "#9ca3af",
@@ -59,10 +59,72 @@ const colors = {
59
59
  };
60
60
 
61
61
  // Use light mode by default (can be made dynamic later)
62
- const isDark =
63
- typeof window !== "undefined" &&
64
- window.matchMedia?.("(prefers-color-scheme: dark)").matches;
65
- const theme = isDark ? colors.dark : colors.light;
62
+ const getIsDark = () => {
63
+ if (typeof document !== "undefined") {
64
+ const root = document.documentElement;
65
+ if (root.classList.contains("dark")) {
66
+ return true;
67
+ }
68
+ if (root.classList.contains("light")) {
69
+ return false;
70
+ }
71
+ }
72
+
73
+ return (
74
+ typeof window !== "undefined" &&
75
+ window.matchMedia?.("(prefers-color-scheme: dark)").matches
76
+ );
77
+ };
78
+
79
+ const themeVars = {
80
+ bg: "var(--ai-bg)",
81
+ bgSecondary: "var(--ai-bg-secondary)",
82
+ bgTertiary: "var(--ai-bg-tertiary)",
83
+ border: "var(--ai-border)",
84
+ borderLight: "var(--ai-border-light)",
85
+ text: "var(--ai-text)",
86
+ textSecondary: "var(--ai-text-secondary)",
87
+ textTertiary: "var(--ai-text-tertiary)",
88
+ shadow: "var(--ai-shadow)",
89
+ shadowMd: "var(--ai-shadow-md)",
90
+ shadowLg: "var(--ai-shadow-lg)",
91
+ shadowXl: "var(--ai-shadow-xl)",
92
+ } as const;
93
+
94
+ const applyThemeVariables = () => {
95
+ if (typeof document === "undefined") {
96
+ return;
97
+ }
98
+
99
+ const nextTheme = getIsDark() ? colors.dark : colors.light;
100
+ const root = document.documentElement;
101
+
102
+ root.style.setProperty("--ai-bg", nextTheme.bg);
103
+ root.style.setProperty("--ai-bg-secondary", nextTheme.bgSecondary);
104
+ root.style.setProperty("--ai-bg-tertiary", nextTheme.bgTertiary);
105
+ root.style.setProperty("--ai-border", nextTheme.border);
106
+ root.style.setProperty("--ai-border-light", nextTheme.borderLight);
107
+ root.style.setProperty("--ai-text", nextTheme.text);
108
+ root.style.setProperty("--ai-text-secondary", nextTheme.textSecondary);
109
+ root.style.setProperty("--ai-text-tertiary", nextTheme.textTertiary);
110
+ root.style.setProperty("--ai-shadow", nextTheme.shadow);
111
+ root.style.setProperty("--ai-shadow-md", nextTheme.shadowMd);
112
+ root.style.setProperty("--ai-shadow-lg", nextTheme.shadowLg);
113
+ root.style.setProperty("--ai-shadow-xl", nextTheme.shadowXl);
114
+ };
115
+
116
+ if (typeof window !== "undefined") {
117
+ applyThemeVariables();
118
+
119
+ const media = window.matchMedia?.("(prefers-color-scheme: dark)");
120
+ media?.addEventListener?.("change", applyThemeVariables);
121
+
122
+ const observer = new MutationObserver(() => applyThemeVariables());
123
+ observer.observe(document.documentElement, {
124
+ attributes: true,
125
+ attributeFilter: ["class"],
126
+ });
127
+ }
66
128
 
67
129
  export const aiStyles = {
68
130
  // Input field
@@ -71,13 +133,15 @@ export const aiStyles = {
71
133
  padding: "12px 40px 12px 16px",
72
134
  fontSize: "14px",
73
135
  lineHeight: "1.5",
74
- color: theme.text,
75
- background: theme.bg,
76
- border: `1px solid ${theme.border}`,
136
+ color: themeVars.text,
137
+ background: themeVars.bg,
138
+ border: `1px solid ${themeVars.border}`,
139
+ borderColor: themeVars.border,
77
140
  borderRadius: "8px",
78
141
  outline: "none",
79
142
  transition: "all 0.2s",
80
143
  fontFamily: "inherit",
144
+ boxShadow: "none",
81
145
  } as React.CSSProperties,
82
146
 
83
147
  inputFocus: {
@@ -107,17 +171,17 @@ export const aiStyles = {
107
171
  padding: "0",
108
172
  border: "none",
109
173
  borderRadius: "6px",
110
- background: colors.primary,
111
- color: "#ffffff",
174
+ background: "transparent",
175
+ color: colors.primary,
112
176
  cursor: "pointer",
113
177
  transition: "all 0.2s",
114
- boxShadow: theme.shadowMd,
178
+ boxShadow: "none",
115
179
  } as React.CSSProperties,
116
180
 
117
181
  inputAiButtonHover: {
118
- background: colors.primaryHover,
119
- boxShadow: theme.shadowLg,
120
- transform: "translateY(-50%) scale(1.05)",
182
+ background: `${colors.primary}33`,
183
+ boxShadow: "none",
184
+ transform: "translateY(-50%)",
121
185
  } as React.CSSProperties,
122
186
 
123
187
  // Textarea
@@ -127,14 +191,16 @@ export const aiStyles = {
127
191
  padding: "12px 40px 12px 16px",
128
192
  fontSize: "14px",
129
193
  lineHeight: "1.5",
130
- color: theme.text,
131
- background: theme.bg,
132
- border: `1px solid ${theme.border}`,
194
+ color: themeVars.text,
195
+ background: themeVars.bg,
196
+ border: `1px solid ${themeVars.border}`,
197
+ borderColor: themeVars.border,
133
198
  borderRadius: "8px",
134
199
  outline: "none",
135
200
  transition: "all 0.2s",
136
201
  fontFamily: "inherit",
137
- resize: "vertical" as const,
202
+ resize: "none" as const,
203
+ boxShadow: "none",
138
204
  } as React.CSSProperties,
139
205
 
140
206
  textareaFocus: {
@@ -159,17 +225,17 @@ export const aiStyles = {
159
225
  padding: "0",
160
226
  border: "none",
161
227
  borderRadius: "6px",
162
- background: colors.primary,
163
- color: "#ffffff",
228
+ background: "transparent",
229
+ color: colors.primary,
164
230
  cursor: "pointer",
165
231
  transition: "all 0.2s",
166
- boxShadow: theme.shadowMd,
232
+ boxShadow: "none",
167
233
  } as React.CSSProperties,
168
234
 
169
235
  textareaAiButtonHover: {
170
- background: colors.primaryHover,
171
- boxShadow: theme.shadowLg,
172
- transform: "scale(1.05)",
236
+ background: `${colors.primary}33`,
237
+ boxShadow: "none",
238
+ transform: "none",
173
239
  } as React.CSSProperties,
174
240
 
175
241
  // Button
@@ -188,13 +254,13 @@ export const aiStyles = {
188
254
  borderRadius: "8px",
189
255
  cursor: "pointer" as const,
190
256
  transition: "all 0.2s",
191
- boxShadow: theme.shadowMd,
257
+ boxShadow: themeVars.shadowMd,
192
258
  fontFamily: "inherit",
193
259
  } as React.CSSProperties,
194
260
 
195
261
  buttonHover: {
196
262
  background: colors.primaryHover,
197
- boxShadow: theme.shadowLg,
263
+ boxShadow: themeVars.shadowLg,
198
264
  transform: "translateY(-1px)",
199
265
  } as React.CSSProperties,
200
266
 
@@ -210,9 +276,9 @@ export const aiStyles = {
210
276
  padding: "12px 16px",
211
277
  fontSize: "14px",
212
278
  lineHeight: "1.5",
213
- color: theme.text,
214
- background: theme.bg,
215
- border: `1px solid ${theme.border}`,
279
+ color: themeVars.text,
280
+ background: themeVars.bg,
281
+ border: `1px solid ${themeVars.border}`,
216
282
  borderRadius: "8px",
217
283
  outline: "none",
218
284
  transition: "all 0.2s",
@@ -232,18 +298,18 @@ export const aiStyles = {
232
298
  justifyContent: "center" as const,
233
299
  width: "40px",
234
300
  height: "40px",
235
- border: `1px solid ${theme.border}`,
301
+ border: `1px solid ${themeVars.border}`,
236
302
  borderRadius: "8px",
237
- background: theme.bg,
238
- color: theme.text,
303
+ background: themeVars.bg,
304
+ color: themeVars.text,
239
305
  cursor: "pointer" as const,
240
306
  transition: "all 0.2s",
241
- boxShadow: theme.shadowMd,
307
+ boxShadow: themeVars.shadowMd,
242
308
  } as React.CSSProperties,
243
309
 
244
310
  statusButtonHover: {
245
- background: theme.bgSecondary,
246
- boxShadow: theme.shadowLg,
311
+ background: themeVars.bgSecondary,
312
+ boxShadow: themeVars.shadowLg,
247
313
  transform: "scale(1.05)",
248
314
  } as React.CSSProperties,
249
315
 
@@ -259,12 +325,12 @@ export const aiStyles = {
259
325
  minWidth: "320px",
260
326
  maxWidth: "400px",
261
327
  padding: "16px",
262
- background: theme.bg,
263
- border: `1px solid ${theme.border}`,
328
+ background: themeVars.bg,
329
+ border: `1px solid ${themeVars.border}`,
264
330
  borderRadius: "12px",
265
- boxShadow: theme.shadowXl,
331
+ boxShadow: themeVars.shadowXl,
266
332
  fontSize: "12px",
267
- color: theme.text,
333
+ color: themeVars.text,
268
334
  pointerEvents: "auto" as const,
269
335
  } as React.CSSProperties,
270
336
 
@@ -273,13 +339,13 @@ export const aiStyles = {
273
339
  fontSize: "16px",
274
340
  paddingBottom: "12px",
275
341
  marginBottom: "12px",
276
- borderBottom: `1px solid ${theme.borderLight}`,
277
- color: theme.text,
342
+ borderBottom: `1px solid ${themeVars.borderLight}`,
343
+ color: themeVars.text,
278
344
  } as React.CSSProperties,
279
345
 
280
346
  tooltipSection: {
281
347
  padding: "12px 0",
282
- borderTop: `1px solid ${theme.borderLight}`,
348
+ borderTop: `1px solid ${themeVars.borderLight}`,
283
349
  } as React.CSSProperties,
284
350
 
285
351
  tooltipSectionFirst: {
@@ -291,7 +357,7 @@ export const aiStyles = {
291
357
  fontWeight: 600,
292
358
  marginBottom: "8px",
293
359
  fontSize: "11px",
294
- color: theme.textSecondary,
360
+ color: themeVars.textSecondary,
295
361
  textTransform: "uppercase" as const,
296
362
  letterSpacing: "0.05em",
297
363
  } as React.CSSProperties,
@@ -305,7 +371,7 @@ export const aiStyles = {
305
371
  } as React.CSSProperties,
306
372
 
307
373
  tooltipLabel: {
308
- color: theme.textSecondary,
374
+ color: themeVars.textSecondary,
309
375
  fontSize: "12px",
310
376
  } as React.CSSProperties,
311
377
 
@@ -313,13 +379,13 @@ export const aiStyles = {
313
379
  fontFamily:
314
380
  'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace',
315
381
  fontSize: "12px",
316
- color: theme.text,
382
+ color: themeVars.text,
317
383
  fontWeight: 500,
318
384
  } as React.CSSProperties,
319
385
 
320
386
  tooltipValueBold: {
321
387
  fontWeight: 700,
322
- color: theme.text,
388
+ color: themeVars.text,
323
389
  } as React.CSSProperties,
324
390
 
325
391
  tooltipValueSuccess: {
@@ -338,7 +404,7 @@ export const aiStyles = {
338
404
  justifyContent: "space-between" as const,
339
405
  paddingTop: "12px",
340
406
  marginTop: "8px",
341
- borderTop: `1px solid ${theme.borderLight}`,
407
+ borderTop: `1px solid ${themeVars.borderLight}`,
342
408
  } as React.CSSProperties,
343
409
 
344
410
  tooltipLink: {
@@ -406,9 +472,9 @@ export const aiStyles = {
406
472
  maxWidth: "600px",
407
473
  maxHeight: "90vh",
408
474
  overflow: "auto" as const,
409
- background: theme.bg,
475
+ background: themeVars.bg,
410
476
  borderRadius: "12px",
411
- boxShadow: theme.shadowXl,
477
+ boxShadow: themeVars.shadowXl,
412
478
  padding: "0",
413
479
  animation: "ai-slideUp 0.3s ease-out",
414
480
  } as React.CSSProperties,
@@ -418,14 +484,14 @@ export const aiStyles = {
418
484
  alignItems: "center" as const,
419
485
  justifyContent: "space-between" as const,
420
486
  padding: "20px 24px",
421
- borderBottom: `1px solid ${theme.borderLight}`,
487
+ borderBottom: `1px solid ${themeVars.borderLight}`,
422
488
  } as React.CSSProperties,
423
489
 
424
490
  modalTitle: {
425
491
  fontSize: "18px",
426
492
  fontWeight: 600,
427
493
  margin: 0,
428
- color: theme.text,
494
+ color: themeVars.text,
429
495
  } as React.CSSProperties,
430
496
 
431
497
  modalCloseButton: {
@@ -438,7 +504,7 @@ export const aiStyles = {
438
504
  border: "none",
439
505
  borderRadius: "6px",
440
506
  background: "transparent",
441
- color: theme.textSecondary,
507
+ color: themeVars.textSecondary,
442
508
  fontSize: "24px",
443
509
  lineHeight: "1",
444
510
  cursor: "pointer" as const,
@@ -446,13 +512,13 @@ export const aiStyles = {
446
512
  } as React.CSSProperties,
447
513
 
448
514
  modalCloseButtonHover: {
449
- background: theme.bgSecondary,
450
- color: theme.text,
515
+ background: themeVars.bgSecondary,
516
+ color: themeVars.text,
451
517
  } as React.CSSProperties,
452
518
 
453
519
  modalBody: {
454
520
  padding: "24px",
455
- color: theme.textSecondary,
521
+ color: themeVars.textSecondary,
456
522
  lineHeight: "1.6",
457
523
  } as React.CSSProperties,
458
524
 
@@ -461,7 +527,7 @@ export const aiStyles = {
461
527
  gap: "12px",
462
528
  justifyContent: "flex-end" as const,
463
529
  padding: "20px 24px",
464
- borderTop: `1px solid ${theme.borderLight}`,
530
+ borderTop: `1px solid ${themeVars.borderLight}`,
465
531
  } as React.CSSProperties,
466
532
 
467
533
  modalLabel: {
@@ -469,7 +535,7 @@ export const aiStyles = {
469
535
  marginBottom: "8px",
470
536
  fontSize: "14px",
471
537
  fontWeight: 500,
472
- color: theme.text,
538
+ color: themeVars.text,
473
539
  } as React.CSSProperties,
474
540
 
475
541
  modalInputGroup: {
@@ -478,14 +544,14 @@ export const aiStyles = {
478
544
 
479
545
  // Buttons variants
480
546
  buttonSecondary: {
481
- background: theme.bgSecondary,
482
- color: theme.text,
483
- border: `1px solid ${theme.border}`,
547
+ background: themeVars.bgSecondary,
548
+ color: themeVars.text,
549
+ border: `1px solid ${themeVars.border}`,
484
550
  } as React.CSSProperties,
485
551
 
486
552
  buttonSecondaryHover: {
487
- background: theme.bgTertiary,
488
- borderColor: theme.borderLight,
553
+ background: themeVars.bgTertiary,
554
+ borderColor: themeVars.borderLight,
489
555
  } as React.CSSProperties,
490
556
 
491
557
  // Spinner