@timbal-ai/timbal-react 0.4.0 → 0.5.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.
package/dist/styles.css CHANGED
@@ -1,16 +1,313 @@
1
1
  /*
2
- * Optional companion styles for `@timbal-ai/timbal-react`.
2
+ * Complete companion stylesheet for `@timbal-ai/timbal-react`.
3
3
  *
4
- * Import this once from your app entry to get the polished defaults that
5
- * the blueprint used inline:
4
+ * Import this once from your app entry to get a fully working theme:
6
5
  *
7
6
  * import "@timbal-ai/timbal-react/styles.css";
8
7
  *
9
- * Tailwind v4 is required for the design tokens (`var(--primary)`, etc.).
10
- * The package itself ships no bundled CSS — you can drop this file entirely
11
- * and ship your own.
8
+ * The package's components are written exclusively against semantic Tailwind
9
+ * tokens (bg-card, text-foreground, border-border, bg-elevated-from/to,
10
+ * shadow-card, …). Every token has a complete light + dark definition here
11
+ * so a consumer's host CSS only needs:
12
+ *
13
+ * @import "tailwindcss";
14
+ * @source "../node_modules/@timbal-ai/timbal-react/dist";
15
+ *
16
+ * Apps that want their own palette can override any --foo / --color-foo
17
+ * variable from their own :root / .dark rules — these rules cascade
18
+ * normally over the ones declared here.
12
19
  */
13
20
 
21
+ /* =============================================================== *
22
+ * Base tokens — shadcn-style :root / .dark pairs *
23
+ * =============================================================== */
24
+
25
+ :root {
26
+ --radius: 0.75rem;
27
+
28
+ /* Studio light — matches the Timbal Platform HeroUI light theme */
29
+ --background: oklch(0.995 0 0);
30
+ --foreground: oklch(0.145 0 0);
31
+ --card: oklch(0.995 0 0);
32
+ --card-foreground: oklch(0.145 0 0);
33
+ --popover: oklch(0.995 0 0);
34
+ --popover-foreground: oklch(0.145 0 0);
35
+ --primary: oklch(0.205 0 0);
36
+ --primary-foreground: oklch(0.985 0 0);
37
+ --secondary: oklch(0.975 0.002 260);
38
+ --secondary-foreground: oklch(0.205 0 0);
39
+ --muted: oklch(0.975 0.002 260);
40
+ --muted-foreground: oklch(0.52 0.014 260);
41
+ --accent: oklch(0.965 0.002 260);
42
+ --accent-foreground: oklch(0.205 0 0);
43
+ --destructive: oklch(0.577 0.245 27.325);
44
+ --destructive-foreground: oklch(0.985 0 0);
45
+ --border: oklch(0.91 0.004 260);
46
+ --input: oklch(0.91 0.004 260);
47
+ --ring: oklch(0.55 0.014 260);
48
+
49
+ /* Sidebar scope — used by StudioSidebar */
50
+ --sidebar: oklch(0.985 0 0);
51
+ --sidebar-foreground: oklch(0.145 0 0);
52
+ --sidebar-primary: oklch(0.205 0 0);
53
+ --sidebar-primary-foreground: oklch(0.985 0 0);
54
+ --sidebar-accent: oklch(0.975 0.002 260);
55
+ --sidebar-accent-foreground: oklch(0.205 0 0);
56
+ --sidebar-border: oklch(0.91 0.004 260);
57
+ --sidebar-ring: oklch(0.55 0.014 260);
58
+
59
+ /* Timbal extension tokens — keep light + dark in sync below */
60
+
61
+ /* Elevated surface gradient (cards, sidebar panel, secondary chrome). */
62
+ --elevated-from: oklch(1 0 0);
63
+ --elevated-to: oklch(0.985 0.002 260 / 0.7);
64
+
65
+ /* Soft playground gradient behind the message column. */
66
+ --playground-from: oklch(0.91 0.004 260 / 0.6);
67
+ --playground-via: oklch(0.965 0.002 260 / 0.3);
68
+ --playground-to: var(--background);
69
+
70
+ /* Composer shell — opaque card with stronger focus border. */
71
+ --composer-bg: oklch(1 0 0);
72
+ --composer-border: oklch(0.91 0.004 260 / 0.6);
73
+ --composer-border-focus: oklch(0.62 0.005 260 / 0.8);
74
+
75
+ /* User message bubble — neutral-200 on light, neutral-700 on dark. */
76
+ --bubble-user: oklch(0.922 0 0);
77
+ --bubble-user-foreground: oklch(0.145 0 0);
78
+
79
+ /* Primary button gradient endpoints — inverts in dark mode. */
80
+ --primary-fill-from: oklch(0.27 0 0);
81
+ --primary-fill-to: oklch(0 0 0);
82
+ --primary-fill-hover-from: oklch(0.32 0 0);
83
+ --primary-fill-hover-to: oklch(0.17 0 0);
84
+ --primary-fill-active-from: oklch(0 0 0);
85
+ --primary-fill-active-to: oklch(0 0 0);
86
+
87
+ /* Secondary button gradient endpoints. */
88
+ --secondary-fill-hover-from: oklch(0.985 0.002 260 / 0.5);
89
+ --secondary-fill-hover-to: oklch(0.965 0.002 260 / 0.65);
90
+ --secondary-fill-active-from: oklch(0.965 0.002 260 / 0.7);
91
+ --secondary-fill-active-to: oklch(0.91 0.004 260 / 0.65);
92
+
93
+ /* Destructive button gradient endpoints. */
94
+ --destructive-fill-hover-from: oklch(0.97 0.06 27 / 0.9);
95
+ --destructive-fill-hover-to: oklch(0.93 0.09 27 / 0.7);
96
+ --destructive-fill-active-from: oklch(0.93 0.09 27 / 0.9);
97
+ --destructive-fill-active-to: oklch(0.86 0.13 27 / 0.65);
98
+
99
+ /* Ghost button hover/active fills. */
100
+ --ghost-fill-hover: oklch(0.965 0.002 260 / 0.7);
101
+ --ghost-fill-active: oklch(0.91 0.004 260 / 0.7);
102
+
103
+ /* Code block surface (markdown). */
104
+ --code-block-bg: oklch(0.98 0 0);
105
+ --code-header-bg: oklch(0.965 0 0);
106
+
107
+ /* Math (KaTeX) display surface. */
108
+ --katex-bg: oklch(0.97 0 0 / 0.6);
109
+ --katex-border: oklch(0.922 0 0);
110
+
111
+ /* Markdown table zebra. */
112
+ --md-table-zebra: oklch(0.97 0 0 / 0.4);
113
+
114
+ /* Scrollbar thumb (light & dark share oklch base, only alpha changes). */
115
+ --scrollbar-thumb: oklch(0.708 0 0 / 0.3);
116
+ --scrollbar-thumb-hover: oklch(0.708 0 0 / 0.5);
117
+
118
+ /* Card shadows. */
119
+ --shadow-card-value: 0 1px 2px -0.5px rgba(0, 0, 0, 0.05);
120
+ --shadow-card-elevated-value: 0 4px 24px rgba(0, 0, 0, 0.06);
121
+
122
+ /* Studio layout (used by StudioSidebar / TimbalStudioShell). */
123
+ --studio-topbar-gap: 0.5rem;
124
+ --studio-topbar-height: 3rem;
125
+ --studio-chrome-pill-height: 2.5rem;
126
+ --studio-inset-top: calc(var(--studio-topbar-gap) + var(--studio-topbar-height));
127
+ --studio-sidebar-gap: 0.75rem;
128
+ --studio-sidebar-width: 14rem;
129
+ --studio-sidebar-width-collapsed: 3.25rem;
130
+ --studio-sidebar-content-gap: 0.5rem;
131
+ --studio-inset-left: calc(
132
+ var(--studio-sidebar-gap) + var(--studio-sidebar-width) +
133
+ var(--studio-sidebar-content-gap)
134
+ );
135
+ --studio-inset-left-collapsed: calc(
136
+ var(--studio-sidebar-gap) + var(--studio-sidebar-width-collapsed) +
137
+ var(--studio-sidebar-content-gap)
138
+ );
139
+ }
140
+
141
+ .dark {
142
+ --background: oklch(0.145 0 0);
143
+ --foreground: oklch(0.985 0 0);
144
+ --card: oklch(0.19 0.005 260);
145
+ --card-foreground: oklch(0.985 0 0);
146
+ --popover: oklch(0.19 0.005 260);
147
+ --popover-foreground: oklch(0.985 0 0);
148
+ --primary: oklch(0.985 0 0);
149
+ --primary-foreground: oklch(0.205 0 0);
150
+ --secondary: oklch(0.22 0.005 260);
151
+ --secondary-foreground: oklch(0.985 0 0);
152
+ --muted: oklch(0.22 0.005 260);
153
+ --muted-foreground: oklch(0.72 0.01 260);
154
+ --accent: oklch(0.25 0.008 260);
155
+ --accent-foreground: oklch(0.985 0 0);
156
+ --destructive: oklch(0.704 0.191 22.216);
157
+ --destructive-foreground: oklch(0.985 0 0);
158
+ --border: oklch(1 0 0 / 0.10);
159
+ --input: oklch(1 0 0 / 0.12);
160
+ --ring: oklch(0.55 0.01 260);
161
+
162
+ --sidebar: oklch(0.19 0.005 260);
163
+ --sidebar-foreground: oklch(0.985 0 0);
164
+ --sidebar-primary: oklch(0.985 0 0);
165
+ --sidebar-primary-foreground: oklch(0.205 0 0);
166
+ --sidebar-accent: oklch(0.25 0.008 260);
167
+ --sidebar-accent-foreground: oklch(0.985 0 0);
168
+ --sidebar-border: oklch(1 0 0 / 0.10);
169
+ --sidebar-ring: oklch(0.55 0.01 260);
170
+
171
+ --elevated-from: oklch(1 0 0 / 0.05);
172
+ --elevated-to: oklch(1 0 0 / 0.025);
173
+
174
+ --playground-from: oklch(0.27 0.005 285);
175
+ --playground-via: oklch(0.19 0.005 260);
176
+ --playground-to: oklch(0.13 0.005 285);
177
+
178
+ --composer-bg: oklch(0.19 0.005 260);
179
+ --composer-border: oklch(1 0 0 / 0.12);
180
+ --composer-border-focus: oklch(1 0 0 / 0.22);
181
+
182
+ --bubble-user: oklch(0.371 0 0);
183
+ --bubble-user-foreground: oklch(0.985 0 0);
184
+
185
+ /* Primary inverts on dark — light gradient on a dark background. */
186
+ --primary-fill-from: oklch(1 0 0);
187
+ --primary-fill-to: oklch(0.92 0 0);
188
+ --primary-fill-hover-from: oklch(1 0 0);
189
+ --primary-fill-hover-to: oklch(0.97 0 0);
190
+ --primary-fill-active-from: oklch(0.92 0 0);
191
+ --primary-fill-active-to: oklch(0.78 0 0);
192
+
193
+ --secondary-fill-hover-from: oklch(1 0 0 / 0.07);
194
+ --secondary-fill-hover-to: oklch(1 0 0 / 0.045);
195
+ --secondary-fill-active-from: oklch(1 0 0 / 0.10);
196
+ --secondary-fill-active-to: oklch(1 0 0 / 0.07);
197
+
198
+ --destructive-fill-hover-from: oklch(0.6 0.2 27 / 0.12);
199
+ --destructive-fill-hover-to: oklch(0.6 0.2 27 / 0.08);
200
+ --destructive-fill-active-from: oklch(0.6 0.2 27 / 0.20);
201
+ --destructive-fill-active-to: oklch(0.6 0.2 27 / 0.12);
202
+
203
+ --ghost-fill-hover: oklch(1 0 0 / 0.10);
204
+ --ghost-fill-active: oklch(1 0 0 / 0.15);
205
+
206
+ --code-block-bg: oklch(0.19 0 0);
207
+ --code-header-bg: oklch(0.22 0 0 / 0.8);
208
+
209
+ --katex-bg: oklch(0.2 0 0 / 0.5);
210
+ --katex-border: oklch(1 0 0 / 0.08);
211
+
212
+ --md-table-zebra: oklch(0.2 0 0 / 0.3);
213
+
214
+ --scrollbar-thumb: oklch(0.708 0 0 / 0.4);
215
+ --scrollbar-thumb-hover: oklch(0.708 0 0 / 0.6);
216
+
217
+ --shadow-card-value: 0 1px 3px rgba(0, 0, 0, 0.22);
218
+ --shadow-card-elevated-value: 0 4px 24px rgba(0, 0, 0, 0.35);
219
+ }
220
+
221
+ /* =============================================================== *
222
+ * Tailwind v4 @theme inline — re-aliases the base tokens above so *
223
+ * `bg-background`, `text-foreground`, `border-border`, etc. all *
224
+ * resolve via var() and flip with .dark. *
225
+ * =============================================================== */
226
+
227
+ @theme inline {
228
+ --radius-sm: calc(var(--radius) - 4px);
229
+ --radius-md: calc(var(--radius) - 2px);
230
+ --radius-lg: var(--radius);
231
+ --radius-xl: calc(var(--radius) + 4px);
232
+
233
+ --color-background: var(--background);
234
+ --color-foreground: var(--foreground);
235
+ --color-card: var(--card);
236
+ --color-card-foreground: var(--card-foreground);
237
+ --color-popover: var(--popover);
238
+ --color-popover-foreground: var(--popover-foreground);
239
+ --color-primary: var(--primary);
240
+ --color-primary-foreground: var(--primary-foreground);
241
+ --color-secondary: var(--secondary);
242
+ --color-secondary-foreground: var(--secondary-foreground);
243
+ --color-muted: var(--muted);
244
+ --color-muted-foreground: var(--muted-foreground);
245
+ --color-accent: var(--accent);
246
+ --color-accent-foreground: var(--accent-foreground);
247
+ --color-destructive: var(--destructive);
248
+ --color-destructive-foreground: var(--destructive-foreground);
249
+ --color-border: var(--border);
250
+ --color-input: var(--input);
251
+ --color-ring: var(--ring);
252
+
253
+ --color-sidebar: var(--sidebar);
254
+ --color-sidebar-foreground: var(--sidebar-foreground);
255
+ --color-sidebar-primary: var(--sidebar-primary);
256
+ --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
257
+ --color-sidebar-accent: var(--sidebar-accent);
258
+ --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
259
+ --color-sidebar-border: var(--sidebar-border);
260
+ --color-sidebar-ring: var(--sidebar-ring);
261
+
262
+ /* Timbal extensions — exposed as colour tokens so they work with
263
+ bg-*, border-*, text-*, from-*, via-*, to-* utilities alike. */
264
+ --color-elevated-from: var(--elevated-from);
265
+ --color-elevated-to: var(--elevated-to);
266
+ --color-playground-from: var(--playground-from);
267
+ --color-playground-via: var(--playground-via);
268
+ --color-playground-to: var(--playground-to);
269
+ --color-composer-bg: var(--composer-bg);
270
+ --color-composer-border: var(--composer-border);
271
+ --color-composer-border-focus: var(--composer-border-focus);
272
+ --color-bubble-user: var(--bubble-user);
273
+ --color-bubble-user-foreground: var(--bubble-user-foreground);
274
+
275
+ --color-primary-fill-from: var(--primary-fill-from);
276
+ --color-primary-fill-to: var(--primary-fill-to);
277
+ --color-primary-fill-hover-from: var(--primary-fill-hover-from);
278
+ --color-primary-fill-hover-to: var(--primary-fill-hover-to);
279
+ --color-primary-fill-active-from: var(--primary-fill-active-from);
280
+ --color-primary-fill-active-to: var(--primary-fill-active-to);
281
+
282
+ --color-secondary-fill-hover-from: var(--secondary-fill-hover-from);
283
+ --color-secondary-fill-hover-to: var(--secondary-fill-hover-to);
284
+ --color-secondary-fill-active-from: var(--secondary-fill-active-from);
285
+ --color-secondary-fill-active-to: var(--secondary-fill-active-to);
286
+
287
+ --color-destructive-fill-hover-from: var(--destructive-fill-hover-from);
288
+ --color-destructive-fill-hover-to: var(--destructive-fill-hover-to);
289
+ --color-destructive-fill-active-from: var(--destructive-fill-active-from);
290
+ --color-destructive-fill-active-to: var(--destructive-fill-active-to);
291
+
292
+ --color-ghost-fill-hover: var(--ghost-fill-hover);
293
+ --color-ghost-fill-active: var(--ghost-fill-active);
294
+
295
+ --color-code-block-bg: var(--code-block-bg);
296
+ --color-code-header-bg: var(--code-header-bg);
297
+
298
+ --shadow-card: var(--shadow-card-value);
299
+ --shadow-card-elevated: var(--shadow-card-elevated-value);
300
+ }
301
+
302
+ /* Allow the `dark` Tailwind variant to be triggered by an ancestor `.dark`
303
+ class. Apps using next-themes / a manual toggle just add/remove `.dark`
304
+ from `<html>` and every utility flips together with the base tokens. */
305
+ @custom-variant dark (&:is(.dark *));
306
+
307
+ /* =============================================================== *
308
+ * Polish — markdown, shiki, katex, scrollbars *
309
+ * =============================================================== */
310
+
14
311
  /* ── Markdown inline code ── */
15
312
  .dark code:not(pre code) {
16
313
  background-color: oklch(0.269 0 0 / 0.8);
@@ -18,14 +315,14 @@
18
315
 
19
316
  /* ── Shiki dual-theme support ── */
20
317
  .shiki-wrapper pre {
21
- background: var(--shiki-light-bg, oklch(0.98 0 0)) !important;
318
+ background: var(--shiki-light-bg, var(--code-block-bg)) !important;
22
319
  }
23
320
  .shiki-wrapper code,
24
321
  .shiki-wrapper code span {
25
322
  color: var(--shiki-light, inherit);
26
323
  }
27
324
  .dark .shiki-wrapper pre {
28
- background: var(--shiki-dark-bg, oklch(0.13 0 0)) !important;
325
+ background: var(--shiki-dark-bg, var(--code-block-bg)) !important;
29
326
  }
30
327
  .dark .shiki-wrapper code,
31
328
  .dark .shiki-wrapper code span {
@@ -55,16 +352,12 @@
55
352
  .katex-display {
56
353
  margin: 1.25rem 0 !important;
57
354
  padding: 1rem 1.25rem;
58
- background: oklch(0.97 0 0 / 0.6);
59
- border: 1px solid oklch(0.922 0 0);
355
+ background: var(--katex-bg);
356
+ border: 1px solid var(--katex-border);
60
357
  border-radius: 0.5rem;
61
358
  overflow-x: auto;
62
359
  overflow-y: hidden;
63
360
  }
64
- .dark .katex-display {
65
- background: oklch(0.2 0 0 / 0.5);
66
- border-color: oklch(1 0 0 / 0.08);
67
- }
68
361
  .katex-display > .katex {
69
362
  text-align: center;
70
363
  }
@@ -80,10 +373,7 @@
80
373
 
81
374
  /* ── Markdown table zebra striping ── */
82
375
  .aui-md-table tbody tr:nth-child(even) {
83
- background: oklch(0.97 0 0 / 0.4);
84
- }
85
- .dark .aui-md-table tbody tr:nth-child(even) {
86
- background: oklch(0.2 0 0 / 0.3);
376
+ background: var(--md-table-zebra);
87
377
  }
88
378
 
89
379
  /* ── Code header polish ── */
@@ -140,7 +430,7 @@
140
430
  .aui-thread-root,
141
431
  .aui-thread-root * {
142
432
  scrollbar-width: thin;
143
- scrollbar-color: oklch(0.708 0 0 / 0.3) transparent;
433
+ scrollbar-color: var(--scrollbar-thumb) transparent;
144
434
  }
145
435
 
146
436
  .aui-thread-root *::-webkit-scrollbar {
@@ -154,7 +444,7 @@
154
444
  }
155
445
 
156
446
  .aui-thread-root *::-webkit-scrollbar-thumb {
157
- background: oklch(0.708 0 0 / 0.3);
447
+ background: var(--scrollbar-thumb);
158
448
  border-radius: 4px;
159
449
  border: 2px solid transparent;
160
450
  background-clip: content-box;
@@ -162,19 +452,19 @@
162
452
  }
163
453
 
164
454
  .aui-thread-root *::-webkit-scrollbar-thumb:hover {
165
- background: oklch(0.708 0 0 / 0.5);
455
+ background: var(--scrollbar-thumb-hover);
166
456
  background-clip: content-box;
167
457
  }
168
458
 
169
- .dark .aui-thread-root,
170
- .dark .aui-thread-root * {
171
- scrollbar-color: oklch(0.708 0 0 / 0.4) transparent;
172
- }
173
-
174
- .dark .aui-thread-root *::-webkit-scrollbar-thumb {
175
- background: oklch(0.708 0 0 / 0.4);
176
- }
459
+ /* =============================================================== *
460
+ * Component fixes — baked in so consumers don't need overrides *
461
+ * =============================================================== */
177
462
 
178
- .dark .aui-thread-root *::-webkit-scrollbar-thumb:hover {
179
- background: oklch(0.708 0 0 / 0.6);
463
+ /* The thread viewport footer no longer paints its own background. The
464
+ thread root already paints bg-background, so the sticky footer must
465
+ stay transparent — otherwise a token mismatch surfaces as a coloured
466
+ strip behind the composer. */
467
+ .aui-thread-viewport-footer {
468
+ background: transparent !important;
469
+ border-radius: 0 !important;
180
470
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@timbal-ai/timbal-react",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "React components and runtime for building Timbal chat UIs",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",
@@ -36,6 +36,7 @@
36
36
  },
37
37
  "dependencies": {
38
38
  "@assistant-ui/react-markdown": "^0.12.3",
39
+ "@paper-design/shaders-react": "^0.0.76",
39
40
  "@radix-ui/react-avatar": "^1.1.11",
40
41
  "@radix-ui/react-dialog": "^1.1.15",
41
42
  "@radix-ui/react-slot": "^1.2.4",