@redbamboo/ui 0.1.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.
Files changed (73) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +78 -0
  3. package/dist/components/app-header.d.ts +14 -0
  4. package/dist/components/app-header.d.ts.map +1 -0
  5. package/dist/components/badge.d.ts +8 -0
  6. package/dist/components/badge.d.ts.map +1 -0
  7. package/dist/components/button.d.ts +9 -0
  8. package/dist/components/button.d.ts.map +1 -0
  9. package/dist/components/card.d.ts +12 -0
  10. package/dist/components/card.d.ts.map +1 -0
  11. package/dist/components/collapsible.d.ts +6 -0
  12. package/dist/components/collapsible.d.ts.map +1 -0
  13. package/dist/components/dialog.d.ts +18 -0
  14. package/dist/components/dialog.d.ts.map +1 -0
  15. package/dist/components/dropdown-menu.d.ts +25 -0
  16. package/dist/components/dropdown-menu.d.ts.map +1 -0
  17. package/dist/components/input.d.ts +4 -0
  18. package/dist/components/input.d.ts.map +1 -0
  19. package/dist/components/json-highlight.d.ts +4 -0
  20. package/dist/components/json-highlight.d.ts.map +1 -0
  21. package/dist/components/label.d.ts +4 -0
  22. package/dist/components/label.d.ts.map +1 -0
  23. package/dist/components/modal.d.ts +33 -0
  24. package/dist/components/modal.d.ts.map +1 -0
  25. package/dist/components/popover.d.ts +10 -0
  26. package/dist/components/popover.d.ts.map +1 -0
  27. package/dist/components/scroll-area.d.ts +5 -0
  28. package/dist/components/scroll-area.d.ts.map +1 -0
  29. package/dist/components/select.d.ts +13 -0
  30. package/dist/components/select.d.ts.map +1 -0
  31. package/dist/components/separator.d.ts +4 -0
  32. package/dist/components/separator.d.ts.map +1 -0
  33. package/dist/components/slider.d.ts +4 -0
  34. package/dist/components/slider.d.ts.map +1 -0
  35. package/dist/components/switch.d.ts +6 -0
  36. package/dist/components/switch.d.ts.map +1 -0
  37. package/dist/components/table.d.ts +11 -0
  38. package/dist/components/table.d.ts.map +1 -0
  39. package/dist/components/tabs.d.ts +11 -0
  40. package/dist/components/tabs.d.ts.map +1 -0
  41. package/dist/components/tooltip.d.ts +7 -0
  42. package/dist/components/tooltip.d.ts.map +1 -0
  43. package/dist/index.css +2 -0
  44. package/dist/index.d.ts +24 -0
  45. package/dist/index.d.ts.map +1 -0
  46. package/dist/index.js +2648 -0
  47. package/dist/utils.d.ts +3 -0
  48. package/dist/utils.d.ts.map +1 -0
  49. package/package.json +49 -0
  50. package/src/components/app-header.css +40 -0
  51. package/src/components/app-header.tsx +57 -0
  52. package/src/components/badge.tsx +52 -0
  53. package/src/components/button.tsx +58 -0
  54. package/src/components/card.tsx +103 -0
  55. package/src/components/collapsible.tsx +21 -0
  56. package/src/components/dialog.tsx +155 -0
  57. package/src/components/dropdown-menu.tsx +240 -0
  58. package/src/components/input.tsx +20 -0
  59. package/src/components/json-highlight.tsx +84 -0
  60. package/src/components/label.tsx +21 -0
  61. package/src/components/modal.tsx +114 -0
  62. package/src/components/popover.tsx +90 -0
  63. package/src/components/scroll-area.tsx +52 -0
  64. package/src/components/select.tsx +145 -0
  65. package/src/components/separator.tsx +23 -0
  66. package/src/components/slider.tsx +41 -0
  67. package/src/components/switch.tsx +30 -0
  68. package/src/components/table.tsx +114 -0
  69. package/src/components/tabs.tsx +80 -0
  70. package/src/components/tooltip.tsx +64 -0
  71. package/src/index.ts +141 -0
  72. package/src/tokens.css +397 -0
  73. package/src/utils.ts +6 -0
package/src/tokens.css ADDED
@@ -0,0 +1,397 @@
1
+ /*
2
+ * @redbamboo/ui — Design System
3
+ *
4
+ * Single source of truth for the RedBamboo design system.
5
+ * Apps import this and set their brand color:
6
+ *
7
+ * @import "tailwindcss";
8
+ * @import "tw-animate-css";
9
+ * @import "@redbamboo/ui/tokens.css";
10
+ *
11
+ * :root, :root.dark { --brand: #E55B5B; }
12
+ */
13
+
14
+ @custom-variant dark (&:is(.dark *));
15
+
16
+ /* ── Semantic theme tokens ──────────────────────────────────────────── */
17
+
18
+ @theme {
19
+ --color-surface-deep: #262830;
20
+ --color-surface-base: #2E3038;
21
+ --color-surface-elevated: #363842;
22
+ --color-border-subtle: #43454F;
23
+
24
+ --color-accent-teal: #26A69A;
25
+ --color-accent-gold: #D4AA4F;
26
+ --color-accent-red: #E55B5B;
27
+ --color-accent-purple: #7C4DFF;
28
+
29
+ --color-text-primary: #D0D1D6;
30
+ --color-text-muted: #9B9CA2;
31
+ --color-text-disabled: #6B6F77;
32
+
33
+ --color-status-idle: #2E2E34;
34
+ }
35
+
36
+ /* ── Tailwind theme mapping ─────────────────────────────────────────── */
37
+
38
+ @theme inline {
39
+ --font-heading: "Inter Variable", "Inter", system-ui, sans-serif;
40
+ --font-sans: "Inter Variable", "Inter", system-ui, sans-serif;
41
+ --font-mono: "JetBrains Mono Variable", "JetBrains Mono", ui-monospace, monospace;
42
+ --font-serif: "Lora Variable", "Lora", Georgia, serif;
43
+
44
+ --color-background: var(--background);
45
+ --color-foreground: var(--foreground);
46
+ --color-card: var(--card);
47
+ --color-card-foreground: var(--card-foreground);
48
+ --color-popover: var(--popover);
49
+ --color-popover-foreground: var(--popover-foreground);
50
+ --color-primary: var(--primary);
51
+ --color-primary-foreground: var(--primary-foreground);
52
+ --color-secondary: var(--secondary);
53
+ --color-secondary-foreground: var(--secondary-foreground);
54
+ --color-muted: var(--muted);
55
+ --color-muted-foreground: var(--muted-foreground);
56
+ --color-accent: var(--accent);
57
+ --color-accent-foreground: var(--accent-foreground);
58
+ --color-destructive: var(--destructive);
59
+ --color-border: var(--border);
60
+ --color-input: var(--input);
61
+ --color-ring: var(--ring);
62
+ --color-contrast: var(--contrast);
63
+
64
+ --color-chart-1: var(--chart-1);
65
+ --color-chart-2: var(--chart-2);
66
+ --color-chart-3: var(--chart-3);
67
+ --color-chart-4: var(--chart-4);
68
+ --color-chart-5: var(--chart-5);
69
+
70
+ --color-sidebar: var(--sidebar);
71
+ --color-sidebar-foreground: var(--sidebar-foreground);
72
+ --color-sidebar-primary: var(--sidebar-primary);
73
+ --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
74
+ --color-sidebar-accent: var(--sidebar-accent);
75
+ --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
76
+ --color-sidebar-border: var(--sidebar-border);
77
+ --color-sidebar-ring: var(--sidebar-ring);
78
+
79
+ --radius-sm: calc(var(--radius) * 0.6);
80
+ --radius-md: calc(var(--radius) * 0.8);
81
+ --radius-lg: var(--radius);
82
+ --radius-xl: calc(var(--radius) * 1.4);
83
+ --radius-2xl: calc(var(--radius) * 1.8);
84
+ --radius-3xl: calc(var(--radius) * 2.2);
85
+ --radius-4xl: calc(var(--radius) * 2.6);
86
+ }
87
+
88
+ /* ── Light palette (default) ───────────────────────────────────────── */
89
+
90
+ :root {
91
+ color-scheme: light;
92
+
93
+ --brand: #E55B5B;
94
+
95
+ --background: #FAFBFC;
96
+ --foreground: #1F2328;
97
+ --card: #FFFFFF;
98
+ --card-foreground: #1F2328;
99
+ --popover: #FFFFFF;
100
+ --popover-foreground: #1F2328;
101
+ --primary: var(--brand);
102
+ --primary-foreground: #FFFFFF;
103
+ --secondary: #F0F1F3;
104
+ --secondary-foreground: #1F2328;
105
+ --muted: #F0F1F3;
106
+ --muted-foreground: #656D76;
107
+ --accent: #F0F1F3;
108
+ --accent-foreground: #1F2328;
109
+ --destructive: #E55B5B;
110
+ --border: #D1D5DB;
111
+ --input: #D1D5DB;
112
+ --ring: var(--brand);
113
+ --chart-1: var(--brand);
114
+ --chart-2: #D4AA4F;
115
+ --chart-3: #7C4DFF;
116
+ --chart-4: #26A69A;
117
+ --chart-5: #8B949E;
118
+ --radius: 0.75rem;
119
+ --sidebar: #F0F1F3;
120
+ --sidebar-foreground: #1F2328;
121
+ --sidebar-primary: var(--brand);
122
+ --sidebar-primary-foreground: #FFFFFF;
123
+ --sidebar-accent: #E5E7EB;
124
+ --sidebar-accent-foreground: #1F2328;
125
+ --sidebar-border: #D1D5DB;
126
+ --sidebar-ring: var(--brand);
127
+
128
+ --color-surface-deep: #F0F1F3;
129
+ --color-surface-base: #FAFBFC;
130
+ --color-surface-elevated: #FFFFFF;
131
+ --color-border-subtle: #D1D5DB;
132
+ --color-text-primary: #1F2328;
133
+ --color-text-muted: #656D76;
134
+ --color-text-disabled: #8B949E;
135
+ --color-status-idle: #F0F1F3;
136
+
137
+ --contrast: #000000;
138
+ --strong: #111827;
139
+ --code-bg: #F3F4F6;
140
+ --code-inline-bg: rgba(0, 0, 0, 0.06);
141
+ --table-header-bg: rgba(0, 0, 0, 0.04);
142
+ --scrollbar-thumb: #C1C3C9;
143
+ --scrollbar-thumb-hover: #A1A3A9;
144
+ }
145
+
146
+ /* ── Dark palette ──────────────────────────────────────────────────── */
147
+
148
+ :root.dark {
149
+ color-scheme: dark;
150
+
151
+ --background: #262830;
152
+ --foreground: #D0D1D6;
153
+ --card: #2E3038;
154
+ --card-foreground: #D0D1D6;
155
+ --popover: #2E3038;
156
+ --popover-foreground: #D0D1D6;
157
+ --primary: var(--brand);
158
+ --primary-foreground: #FFFFFF;
159
+ --secondary: #3C3E48;
160
+ --secondary-foreground: #D0D1D6;
161
+ --muted: #2E3038;
162
+ --muted-foreground: #9B9CA2;
163
+ --accent: #3C3E48;
164
+ --accent-foreground: #D0D1D6;
165
+ --destructive: #E55B5B;
166
+ --border: #43454F;
167
+ --input: #3C3E48;
168
+ --ring: var(--brand);
169
+ --chart-1: var(--brand);
170
+ --chart-2: #D4AA4F;
171
+ --chart-3: #7C4DFF;
172
+ --chart-4: #26A69A;
173
+ --chart-5: #6B6F77;
174
+ --sidebar: #262830;
175
+ --sidebar-foreground: #D0D1D6;
176
+ --sidebar-primary: var(--brand);
177
+ --sidebar-primary-foreground: #FFFFFF;
178
+ --sidebar-accent: #2E3038;
179
+ --sidebar-accent-foreground: #D0D1D6;
180
+ --sidebar-border: #43454F;
181
+ --sidebar-ring: var(--brand);
182
+
183
+ --color-surface-deep: #262830;
184
+ --color-surface-base: #2E3038;
185
+ --color-surface-elevated: #363842;
186
+ --color-border-subtle: #43454F;
187
+ --color-text-primary: #D0D1D6;
188
+ --color-text-muted: #9B9CA2;
189
+ --color-text-disabled: #6B6F77;
190
+ --color-status-idle: #2E2E34;
191
+
192
+ --contrast: #FFFFFF;
193
+ --strong: #FFFFFF;
194
+ --code-bg: #1e2028;
195
+ --code-inline-bg: rgba(255, 255, 255, 0.08);
196
+ --table-header-bg: rgba(255, 255, 255, 0.05);
197
+ --scrollbar-thumb: #43454F;
198
+ --scrollbar-thumb-hover: #555760;
199
+ }
200
+
201
+ /* ── Global styles ─────────────────────────────────────────────────── */
202
+
203
+ body {
204
+ margin: 0;
205
+ background: var(--background);
206
+ -webkit-font-smoothing: antialiased;
207
+ -moz-osx-font-smoothing: grayscale;
208
+ }
209
+
210
+ * {
211
+ scrollbar-width: thin;
212
+ scrollbar-color: var(--scrollbar-thumb) transparent;
213
+ }
214
+ *::-webkit-scrollbar {
215
+ width: 6px;
216
+ height: 6px;
217
+ }
218
+ *::-webkit-scrollbar-track {
219
+ background: transparent;
220
+ }
221
+ *::-webkit-scrollbar-thumb {
222
+ background: var(--scrollbar-thumb);
223
+ border-radius: 3px;
224
+ }
225
+ *::-webkit-scrollbar-thumb:hover {
226
+ background: var(--scrollbar-thumb-hover);
227
+ }
228
+
229
+ /* ── Markdown body styles ──────────────────────────────────────────── */
230
+
231
+ .markdown-body h1, .markdown-body h2, .markdown-body h3,
232
+ .markdown-body h4, .markdown-body h5, .markdown-body h6 {
233
+ font-family: var(--font-sans);
234
+ font-weight: 600;
235
+ margin-top: 1.25em;
236
+ margin-bottom: 0.5em;
237
+ line-height: 1.3;
238
+ }
239
+ .markdown-body h1 { font-size: 1.35em; }
240
+ .markdown-body h2 { font-size: 1.15em; }
241
+ .markdown-body h3 { font-size: 1.05em; }
242
+ .markdown-body p { margin: 0.6em 0; }
243
+ .markdown-body p:first-child { margin-top: 0; }
244
+ .markdown-body p:last-child { margin-bottom: 0; }
245
+ .markdown-body ul, .markdown-body ol {
246
+ padding-left: 1.5em;
247
+ margin: 0.5em 0;
248
+ }
249
+ .markdown-body li { margin: 0.2em 0; }
250
+ .markdown-body li::marker { color: var(--muted-foreground); }
251
+ .markdown-body strong { color: var(--strong); }
252
+ .markdown-body a { color: var(--color-accent-teal); text-decoration: underline; }
253
+ .markdown-body blockquote {
254
+ border-left: 3px solid var(--border);
255
+ padding-left: 0.75em;
256
+ color: var(--muted-foreground);
257
+ margin: 0.5em 0;
258
+ }
259
+ .markdown-body pre {
260
+ background: var(--code-bg);
261
+ border-radius: 0.5rem;
262
+ padding: 0.75em 1em;
263
+ margin: 0.6em 0;
264
+ overflow-x: auto;
265
+ font-family: var(--font-mono);
266
+ font-size: 0.85em;
267
+ line-height: 1.5;
268
+ }
269
+ .markdown-body code:not(pre code) {
270
+ background: var(--code-inline-bg);
271
+ padding: 0.15em 0.35em;
272
+ border-radius: 0.25rem;
273
+ font-family: var(--font-mono);
274
+ font-size: 0.85em;
275
+ word-break: break-all;
276
+ }
277
+ .markdown-body {
278
+ overflow-wrap: break-word;
279
+ word-break: break-word;
280
+ }
281
+ .markdown-body a {
282
+ word-break: break-all;
283
+ }
284
+ .markdown-body table {
285
+ border-collapse: collapse;
286
+ margin: 0.5em 0;
287
+ width: 100%;
288
+ font-size: 0.9em;
289
+ }
290
+ .markdown-body th, .markdown-body td {
291
+ border: 1px solid var(--border);
292
+ padding: 0.35em 0.6em;
293
+ }
294
+ .markdown-body th {
295
+ background: var(--table-header-bg);
296
+ font-weight: 600;
297
+ }
298
+ .markdown-body hr {
299
+ border: none;
300
+ border-top: 1px solid var(--border);
301
+ margin: 1em 0;
302
+ }
303
+
304
+ /* ── Chat message animations ───────────────────────────────────────── */
305
+
306
+ @keyframes msg-in-user {
307
+ 0% { opacity: 0; transform: translateX(16px) scale(0.92) rotate(1.5deg); }
308
+ 30% { opacity: 1; transform: translateX(-4px) scale(1.02) rotate(-0.8deg); }
309
+ 55% { transform: translateX(2px) scale(0.99) rotate(0.4deg); }
310
+ 75% { transform: translateX(-1px) scale(1.005) rotate(-0.15deg); }
311
+ 100% { opacity: 1; transform: translateX(0) scale(1) rotate(0deg); }
312
+ }
313
+
314
+ @keyframes msg-in-ai {
315
+ 0% { opacity: 0; transform: translateY(10px) scale(0.96) rotate(-0.6deg); }
316
+ 25% { opacity: 1; transform: translateY(-3px) scale(1.01) rotate(0.3deg); }
317
+ 50% { transform: translateY(1.5px) scale(0.998) rotate(-0.15deg); }
318
+ 70% { transform: translateY(-0.5px) scale(1.002) rotate(0.05deg); }
319
+ 100% { opacity: 1; transform: translateY(0) scale(1) rotate(0deg); }
320
+ }
321
+
322
+ .msg-enter-user {
323
+ animation: msg-in-user 0.45s cubic-bezier(0.23, 1, 0.32, 1) both;
324
+ }
325
+
326
+ .msg-enter-ai {
327
+ animation: msg-in-ai 0.5s cubic-bezier(0.23, 1, 0.32, 1) both;
328
+ }
329
+
330
+ @keyframes square-jiggle {
331
+ 0%, 100% { transform: scale(1.25) rotate(0deg); }
332
+ 25% { transform: scale(1.25) rotate(-4deg) translate(-0.4px, -0.3px); }
333
+ 50% { transform: scale(1.25) rotate(0deg) translate(0, 0.3px); }
334
+ 75% { transform: scale(1.25) rotate(4deg) translate(0.4px, -0.3px); }
335
+ }
336
+
337
+ .square-jiggle {
338
+ animation: square-jiggle 0.6s ease-in-out infinite;
339
+ }
340
+
341
+ .morph-spinner-wrap {
342
+ display: inline-flex;
343
+ align-items: center;
344
+ justify-content: center;
345
+ width: 18px;
346
+ height: 18px;
347
+ flex-shrink: 0;
348
+ }
349
+
350
+ .morph-spinner {
351
+ display: block;
352
+ width: 14px;
353
+ height: 14px;
354
+ background: var(--morph-color, var(--color-accent-teal));
355
+ box-shadow: 0 0 5px var(--morph-color, var(--color-accent-teal));
356
+ transition:
357
+ clip-path 0.5s cubic-bezier(0.34, 1.56, 0.64, 1),
358
+ background 0.4s ease,
359
+ box-shadow 0.4s ease;
360
+ animation: morph-jiggle 0.6s ease-in-out infinite;
361
+ }
362
+
363
+ .morph-bouncing {
364
+ animation: morph-bounce 0.6s ease-out;
365
+ }
366
+
367
+ @keyframes morph-bounce {
368
+ 0% { transform: translateY(0) rotate(0deg) scaleX(1) scaleY(1); }
369
+ 12% { transform: translateY(1px) rotate(0deg) scaleX(1.15) scaleY(0.8); }
370
+ 30% { transform: translateY(-10px) rotate(100deg) scaleX(0.9) scaleY(1.1); }
371
+ 50% { transform: translateY(-13px) rotate(200deg) scaleX(1) scaleY(1); }
372
+ 70% { transform: translateY(-5px) rotate(310deg) scaleX(1.05) scaleY(0.95); }
373
+ 85% { transform: translateY(0px) rotate(360deg) scaleX(1.2) scaleY(0.75); }
374
+ 93% { transform: translateY(0) rotate(360deg) scaleX(0.92) scaleY(1.08); }
375
+ 100% { transform: translateY(0) rotate(360deg) scaleX(1) scaleY(1); }
376
+ }
377
+
378
+ @keyframes morph-jiggle {
379
+ 0%, 100% { transform: scale(1) rotate(0deg); }
380
+ 25% { transform: scale(1.06) rotate(-4deg) translate(-0.4px, -0.3px); }
381
+ 50% { transform: scale(0.97) rotate(0deg) translate(0, 0.3px); }
382
+ 75% { transform: scale(1.04) rotate(4deg) translate(0.4px, -0.3px); }
383
+ }
384
+
385
+ /* ── Base layer ────────────────────────────────────────────────────── */
386
+
387
+ @layer base {
388
+ * {
389
+ @apply border-border outline-ring/50;
390
+ }
391
+ body {
392
+ @apply bg-background text-foreground;
393
+ }
394
+ html {
395
+ @apply font-sans;
396
+ }
397
+ }
package/src/utils.ts ADDED
@@ -0,0 +1,6 @@
1
+ import { clsx, type ClassValue } from "clsx"
2
+ import { twMerge } from "tailwind-merge"
3
+
4
+ export function cn(...inputs: ClassValue[]) {
5
+ return twMerge(clsx(inputs))
6
+ }