@altruist03/ui 0.0.0-stage → 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.
package/dist/index.js ADDED
@@ -0,0 +1,731 @@
1
+ import './index.css';
2
+ import { jsxs, jsx } from 'react/jsx-runtime';
3
+ import { forwardRef, useId, useState } from 'react';
4
+
5
+ // src/utils/cx.ts
6
+ function cx(...parts) {
7
+ return parts.filter(Boolean).join(" ");
8
+ }
9
+
10
+ // src/utils/resolve.ts
11
+ var COLOR_VARS = {
12
+ primary: "var(--al-color-primary)",
13
+ secondary: "var(--al-color-secondary)",
14
+ danger: "var(--al-color-danger)",
15
+ success: "var(--al-color-success)",
16
+ warning: "var(--al-color-warning)",
17
+ text: "var(--al-color-text)",
18
+ textMuted: "var(--al-color-text-muted)",
19
+ border: "var(--al-color-border)",
20
+ surface: "var(--al-color-surface)",
21
+ surfaceMuted: "var(--al-color-surface-muted)"
22
+ };
23
+ var FONT_SIZE_VARS = {
24
+ xs: "var(--al-font-size-xs)",
25
+ sm: "var(--al-font-size-sm)",
26
+ md: "var(--al-font-size-md)",
27
+ lg: "var(--al-font-size-lg)"
28
+ };
29
+ function resolveColor(value) {
30
+ if (!value) return void 0;
31
+ return COLOR_VARS[value] ?? value;
32
+ }
33
+ function resolveFontSize(value) {
34
+ if (value == null || value === "") return void 0;
35
+ if (typeof value === "number") return `${value}px`;
36
+ return FONT_SIZE_VARS[value] ?? value;
37
+ }
38
+ function solidForeground(color) {
39
+ if (!color || color === "primary") return "var(--al-color-on-primary)";
40
+ if (color === "secondary") return "var(--al-color-on-secondary)";
41
+ return "#ffffff";
42
+ }
43
+ function controlVars(color) {
44
+ const accent = resolveColor(color);
45
+ if (!accent) return {};
46
+ return {
47
+ "--al-control-accent": accent,
48
+ "--al-control-border": accent
49
+ };
50
+ }
51
+ function Badge({
52
+ color = "primary",
53
+ variant = "soft",
54
+ fontSize,
55
+ fontFamily,
56
+ className,
57
+ style,
58
+ children,
59
+ ...rest
60
+ }) {
61
+ return /* @__PURE__ */ jsx(
62
+ "span",
63
+ {
64
+ className: cx("al-badge", className),
65
+ "data-variant": variant,
66
+ style: {
67
+ "--al-badge-color": resolveColor(color),
68
+ fontSize: resolveFontSize(fontSize),
69
+ fontFamily,
70
+ ...style
71
+ },
72
+ ...rest,
73
+ children
74
+ }
75
+ );
76
+ }
77
+ var Button = forwardRef(function Button2({
78
+ variant = "solid",
79
+ color = "primary",
80
+ textColor,
81
+ size = "md",
82
+ fontSize,
83
+ fontFamily,
84
+ fullWidth = false,
85
+ loading = false,
86
+ leftIcon,
87
+ rightIcon,
88
+ className,
89
+ style,
90
+ disabled,
91
+ children,
92
+ type = "button",
93
+ ...rest
94
+ }, ref) {
95
+ const accent = resolveColor(color);
96
+ const vars = {
97
+ "--al-btn-bg": accent,
98
+ ...variant === "solid" ? { "--al-btn-fg": textColor ? resolveColor(textColor) : solidForeground(color) } : null,
99
+ ...fontSize != null ? { fontSize: resolveFontSize(fontSize) } : null,
100
+ ...fontFamily ? { fontFamily } : null,
101
+ ...style
102
+ };
103
+ return /* @__PURE__ */ jsxs(
104
+ "button",
105
+ {
106
+ ref,
107
+ type,
108
+ className: cx("al-btn", className),
109
+ "data-variant": variant,
110
+ "data-size": size,
111
+ "data-full-width": fullWidth ? "true" : void 0,
112
+ style: vars,
113
+ disabled: disabled || loading,
114
+ "aria-busy": loading || void 0,
115
+ ...rest,
116
+ children: [
117
+ loading ? /* @__PURE__ */ jsx("span", { className: "al-spinner", "aria-hidden": "true" }) : leftIcon,
118
+ children,
119
+ rightIcon
120
+ ]
121
+ }
122
+ );
123
+ });
124
+ function Card({
125
+ title,
126
+ description,
127
+ footer,
128
+ padding = "md",
129
+ fontSize,
130
+ fontFamily,
131
+ className,
132
+ style,
133
+ children,
134
+ ...rest
135
+ }) {
136
+ const cardStyle = {
137
+ ...fontSize != null ? { fontSize: resolveFontSize(fontSize) } : null,
138
+ ...fontFamily ? { fontFamily } : null,
139
+ ...style
140
+ };
141
+ return /* @__PURE__ */ jsxs("section", { className: cx("al-card", className), "data-padding": padding, style: cardStyle, ...rest, children: [
142
+ title || description ? /* @__PURE__ */ jsxs("header", { className: "al-card-header", children: [
143
+ title ? /* @__PURE__ */ jsx("h2", { className: "al-card-title", children: title }) : null,
144
+ description ? /* @__PURE__ */ jsx("p", { className: "al-card-description", children: description }) : null
145
+ ] }) : null,
146
+ children,
147
+ footer ? /* @__PURE__ */ jsx("footer", { className: "al-card-footer", children: footer }) : null
148
+ ] });
149
+ }
150
+ var Checkbox = forwardRef(function Checkbox2({ label, description, error, fontSize, fontFamily, color, className, style, id, ...rest }, ref) {
151
+ const autoId = useId();
152
+ const checkboxId = id ?? autoId;
153
+ const errorId = `${checkboxId}-error`;
154
+ const descriptionId = `${checkboxId}-description`;
155
+ const accent = resolveColor(color);
156
+ const describedBy = [description ? descriptionId : null, error ? errorId : null].filter(Boolean).join(" ");
157
+ return /* @__PURE__ */ jsxs("div", { className: "al-checkbox-field", style: fontFamily ? { fontFamily } : void 0, children: [
158
+ /* @__PURE__ */ jsxs("label", { className: "al-checkbox", htmlFor: checkboxId, children: [
159
+ /* @__PURE__ */ jsx(
160
+ "input",
161
+ {
162
+ ref,
163
+ id: checkboxId,
164
+ type: "checkbox",
165
+ className: cx("al-checkbox-input", className),
166
+ "aria-invalid": error ? true : void 0,
167
+ "aria-describedby": describedBy || void 0,
168
+ style: {
169
+ accentColor: accent,
170
+ ...style
171
+ },
172
+ ...rest
173
+ }
174
+ ),
175
+ label || description ? /* @__PURE__ */ jsxs("span", { className: "al-checkbox-copy", style: { fontSize: resolveFontSize(fontSize) }, children: [
176
+ label ? /* @__PURE__ */ jsx("span", { className: "al-checkbox-label", children: label }) : null,
177
+ description ? /* @__PURE__ */ jsx("span", { id: descriptionId, className: "al-checkbox-description", children: description }) : null
178
+ ] }) : null
179
+ ] }),
180
+ error ? /* @__PURE__ */ jsx("p", { id: errorId, className: "al-field-error", children: error }) : null
181
+ ] });
182
+ });
183
+ function Field({
184
+ id,
185
+ label,
186
+ required,
187
+ helperText,
188
+ error,
189
+ messageId,
190
+ fontFamily,
191
+ children,
192
+ className
193
+ }) {
194
+ const describedBy = messageId ?? `${id}-message`;
195
+ return /* @__PURE__ */ jsxs("div", { className: cx("al-field", className), style: fontFamily ? { fontFamily } : void 0, children: [
196
+ label ? /* @__PURE__ */ jsxs("label", { className: "al-field-label", htmlFor: id, children: [
197
+ label,
198
+ required ? /* @__PURE__ */ jsx("span", { className: "al-field-required", children: "*" }) : null
199
+ ] }) : null,
200
+ children,
201
+ error ? /* @__PURE__ */ jsx("p", { id: describedBy, className: "al-field-error", children: error }) : helperText ? /* @__PURE__ */ jsx("p", { id: describedBy, className: "al-field-helper", children: helperText }) : null
202
+ ] });
203
+ }
204
+ var FileInput = forwardRef(function FileInput2({
205
+ label,
206
+ helperText,
207
+ error,
208
+ emptyText = "Drop a file here, or browse",
209
+ buttonLabel = "Browse",
210
+ fontSize,
211
+ fontFamily,
212
+ color,
213
+ className,
214
+ style,
215
+ id,
216
+ required,
217
+ multiple,
218
+ onChange,
219
+ ...rest
220
+ }, ref) {
221
+ const autoId = useId();
222
+ const inputId = id ?? autoId;
223
+ const messageId = `${inputId}-message`;
224
+ const [names, setNames] = useState([]);
225
+ const [dragging, setDragging] = useState(false);
226
+ function remember(files) {
227
+ setNames(Array.from(files ?? []).map((file) => file.name));
228
+ }
229
+ function keepDropAlive(event) {
230
+ event.preventDefault();
231
+ setDragging(true);
232
+ }
233
+ return /* @__PURE__ */ jsx(
234
+ Field,
235
+ {
236
+ id: inputId,
237
+ label,
238
+ required,
239
+ helperText,
240
+ error,
241
+ messageId,
242
+ fontFamily,
243
+ className,
244
+ children: /* @__PURE__ */ jsxs(
245
+ "label",
246
+ {
247
+ className: cx("al-file", dragging && "is-dragging"),
248
+ htmlFor: inputId,
249
+ "data-invalid": error ? "true" : void 0,
250
+ style: {
251
+ ...controlVars(color),
252
+ fontSize: resolveFontSize(fontSize),
253
+ ...style
254
+ },
255
+ onDragEnter: keepDropAlive,
256
+ onDragOver: keepDropAlive,
257
+ onDragLeave: () => setDragging(false),
258
+ onDrop: () => setDragging(false),
259
+ children: [
260
+ /* @__PURE__ */ jsx(
261
+ "input",
262
+ {
263
+ ref,
264
+ id: inputId,
265
+ className: "al-file-input",
266
+ type: "file",
267
+ multiple,
268
+ required,
269
+ "aria-invalid": error ? true : void 0,
270
+ "aria-describedby": error || helperText ? messageId : void 0,
271
+ onChange: (event) => {
272
+ remember(event.target.files);
273
+ setDragging(false);
274
+ onChange?.(event);
275
+ },
276
+ ...rest
277
+ }
278
+ ),
279
+ /* @__PURE__ */ jsxs("span", { className: "al-file-copy", children: [
280
+ /* @__PURE__ */ jsx("span", { className: "al-file-title", children: names.length > 0 ? `${names.length} file${names.length === 1 ? "" : "s"} selected` : emptyText }),
281
+ names.length > 0 ? /* @__PURE__ */ jsx("span", { className: "al-file-names", children: names.join(", ") }) : /* @__PURE__ */ jsx("span", { className: "al-file-names", children: "PNG, JPG, or PDF" })
282
+ ] }),
283
+ /* @__PURE__ */ jsx("span", { className: "al-file-button", children: buttonLabel })
284
+ ]
285
+ }
286
+ )
287
+ }
288
+ );
289
+ });
290
+ var FloatingInput = forwardRef(function FloatingInput2({
291
+ label,
292
+ placeholder,
293
+ helperText,
294
+ error,
295
+ size = "md",
296
+ fontSize,
297
+ fontFamily,
298
+ color,
299
+ className,
300
+ style,
301
+ id,
302
+ required,
303
+ value,
304
+ defaultValue,
305
+ onChange,
306
+ ...rest
307
+ }, ref) {
308
+ const autoId = useId();
309
+ const inputId = id ?? autoId;
310
+ const messageId = `${inputId}-message`;
311
+ const [localFilled, setLocalFilled] = useState(() => String(value ?? defaultValue ?? "").length > 0);
312
+ const filled = value != null ? String(value).length > 0 : localFilled;
313
+ return /* @__PURE__ */ jsx(
314
+ Field,
315
+ {
316
+ id: inputId,
317
+ required,
318
+ helperText,
319
+ error,
320
+ messageId,
321
+ fontFamily,
322
+ className,
323
+ children: /* @__PURE__ */ jsxs(
324
+ "div",
325
+ {
326
+ className: "al-float",
327
+ "data-size": size,
328
+ "data-filled": filled ? "true" : "false",
329
+ "data-invalid": error ? "true" : void 0,
330
+ style: controlVars(color),
331
+ children: [
332
+ /* @__PURE__ */ jsx(
333
+ "input",
334
+ {
335
+ ref,
336
+ id: inputId,
337
+ className: "al-control al-float-input",
338
+ placeholder: placeholder ?? " ",
339
+ required,
340
+ ...value != null ? { value } : { defaultValue },
341
+ "aria-invalid": error ? true : void 0,
342
+ "aria-describedby": error || helperText ? messageId : void 0,
343
+ style: {
344
+ fontSize: resolveFontSize(fontSize),
345
+ ...style
346
+ },
347
+ onChange: (event) => {
348
+ if (value == null) setLocalFilled(event.target.value.length > 0);
349
+ onChange?.(event);
350
+ },
351
+ ...rest
352
+ }
353
+ ),
354
+ /* @__PURE__ */ jsxs("label", { className: "al-float-label", htmlFor: inputId, children: [
355
+ label,
356
+ required ? /* @__PURE__ */ jsx("span", { className: "al-field-required", children: "*" }) : null
357
+ ] })
358
+ ]
359
+ }
360
+ )
361
+ }
362
+ );
363
+ });
364
+ var Input = forwardRef(function Input2({
365
+ label,
366
+ helperText,
367
+ error,
368
+ size = "md",
369
+ fontSize,
370
+ fontFamily,
371
+ color,
372
+ leftIcon,
373
+ rightIcon,
374
+ className,
375
+ style,
376
+ id,
377
+ required,
378
+ ...rest
379
+ }, ref) {
380
+ const autoId = useId();
381
+ const inputId = id ?? autoId;
382
+ const messageId = `${inputId}-message`;
383
+ return /* @__PURE__ */ jsx(
384
+ Field,
385
+ {
386
+ id: inputId,
387
+ label,
388
+ required,
389
+ helperText,
390
+ error,
391
+ messageId,
392
+ fontFamily,
393
+ children: /* @__PURE__ */ jsxs("div", { className: cx("al-control-wrap", leftIcon ? "has-left" : void 0, rightIcon ? "has-right" : void 0), children: [
394
+ leftIcon ? /* @__PURE__ */ jsx("span", { className: "al-control-icon left", children: leftIcon }) : null,
395
+ /* @__PURE__ */ jsx(
396
+ "input",
397
+ {
398
+ ref,
399
+ id: inputId,
400
+ className: cx("al-control", className),
401
+ "data-size": size,
402
+ required,
403
+ "aria-invalid": error ? true : void 0,
404
+ "aria-describedby": error || helperText ? messageId : void 0,
405
+ style: {
406
+ ...controlVars(color),
407
+ fontSize: resolveFontSize(fontSize),
408
+ ...style
409
+ },
410
+ ...rest
411
+ }
412
+ ),
413
+ rightIcon ? /* @__PURE__ */ jsx("span", { className: "al-control-icon right", children: rightIcon }) : null
414
+ ] })
415
+ }
416
+ );
417
+ });
418
+ var Select = forwardRef(function Select2({
419
+ label,
420
+ helperText,
421
+ error,
422
+ placeholder,
423
+ options,
424
+ size = "md",
425
+ fontSize,
426
+ fontFamily,
427
+ color,
428
+ className,
429
+ style,
430
+ id,
431
+ required,
432
+ ...rest
433
+ }, ref) {
434
+ const autoId = useId();
435
+ const selectId = id ?? autoId;
436
+ const messageId = `${selectId}-message`;
437
+ return /* @__PURE__ */ jsx(
438
+ Field,
439
+ {
440
+ id: selectId,
441
+ label,
442
+ required,
443
+ helperText,
444
+ error,
445
+ messageId,
446
+ fontFamily,
447
+ children: /* @__PURE__ */ jsxs(
448
+ "select",
449
+ {
450
+ ref,
451
+ id: selectId,
452
+ className: cx("al-control", "al-select", className),
453
+ "data-size": size,
454
+ required,
455
+ "aria-invalid": error ? true : void 0,
456
+ "aria-describedby": error || helperText ? messageId : void 0,
457
+ style: {
458
+ ...controlVars(color),
459
+ fontSize: resolveFontSize(fontSize),
460
+ ...style
461
+ },
462
+ ...rest,
463
+ children: [
464
+ placeholder ? /* @__PURE__ */ jsx("option", { value: "", disabled: true, children: placeholder }) : null,
465
+ options.map((option) => /* @__PURE__ */ jsx("option", { value: option.value, disabled: option.disabled, children: option.label }, option.value))
466
+ ]
467
+ }
468
+ )
469
+ }
470
+ );
471
+ });
472
+ function cellValue(row, key) {
473
+ const value = row[key];
474
+ if (value == null || value === "") return "\u2014";
475
+ if (typeof value === "string" || typeof value === "number") return value;
476
+ return String(value);
477
+ }
478
+ function Table({
479
+ columns,
480
+ rows,
481
+ getRowKey,
482
+ caption,
483
+ emptyLabel = "No records",
484
+ size = "md",
485
+ striped = false,
486
+ fontSize,
487
+ fontFamily,
488
+ className,
489
+ style
490
+ }) {
491
+ return /* @__PURE__ */ jsx("div", { className: "al-table-wrap", children: /* @__PURE__ */ jsxs(
492
+ "table",
493
+ {
494
+ className: cx("al-table", className),
495
+ "data-size": size,
496
+ "data-striped": striped ? "true" : void 0,
497
+ style: {
498
+ fontSize: resolveFontSize(fontSize),
499
+ fontFamily,
500
+ ...style
501
+ },
502
+ children: [
503
+ caption ? /* @__PURE__ */ jsx("caption", { className: "al-table-caption", children: caption }) : null,
504
+ /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsx("tr", { children: columns.map((column) => /* @__PURE__ */ jsx("th", { scope: "col", style: { textAlign: column.align, width: column.width }, children: column.header }, column.key)) }) }),
505
+ /* @__PURE__ */ jsx("tbody", { children: rows.length === 0 ? /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx("td", { className: "al-table-empty", colSpan: Math.max(columns.length, 1), children: emptyLabel }) }) : rows.map((row, index) => /* @__PURE__ */ jsx("tr", { children: columns.map((column) => /* @__PURE__ */ jsx("td", { style: { textAlign: column.align }, children: column.render ? column.render(row) : cellValue(row, column.key) }, column.key)) }, getRowKey(row, index))) })
506
+ ]
507
+ }
508
+ ) });
509
+ }
510
+ var Textarea = forwardRef(function Textarea2({
511
+ label,
512
+ helperText,
513
+ error,
514
+ fontSize,
515
+ fontFamily,
516
+ color,
517
+ className,
518
+ style,
519
+ id,
520
+ required,
521
+ rows = 4,
522
+ ...rest
523
+ }, ref) {
524
+ const autoId = useId();
525
+ const textareaId = id ?? autoId;
526
+ const messageId = `${textareaId}-message`;
527
+ return /* @__PURE__ */ jsx(
528
+ Field,
529
+ {
530
+ id: textareaId,
531
+ label,
532
+ required,
533
+ helperText,
534
+ error,
535
+ messageId,
536
+ fontFamily,
537
+ children: /* @__PURE__ */ jsx(
538
+ "textarea",
539
+ {
540
+ ref,
541
+ id: textareaId,
542
+ className: cx("al-control", "al-textarea", className),
543
+ rows,
544
+ required,
545
+ "aria-invalid": error ? true : void 0,
546
+ "aria-describedby": error || helperText ? messageId : void 0,
547
+ style: {
548
+ ...controlVars(color),
549
+ fontSize: resolveFontSize(fontSize),
550
+ ...style
551
+ },
552
+ ...rest
553
+ }
554
+ )
555
+ }
556
+ );
557
+ });
558
+ function Accordion({
559
+ items,
560
+ allowMultiple = false,
561
+ defaultOpenIds = [],
562
+ color,
563
+ fontSize,
564
+ fontFamily,
565
+ className,
566
+ style
567
+ }) {
568
+ const [openIds, setOpenIds] = useState(defaultOpenIds);
569
+ const accent = resolveColor(color);
570
+ function toggle(id) {
571
+ setOpenIds((current) => {
572
+ const isOpen = current.includes(id);
573
+ if (allowMultiple) {
574
+ return isOpen ? current.filter((item) => item !== id) : [...current, id];
575
+ }
576
+ return isOpen ? [] : [id];
577
+ });
578
+ }
579
+ return /* @__PURE__ */ jsx(
580
+ "div",
581
+ {
582
+ className: className ? "accordion " + className : "accordion",
583
+ style: { fontSize: resolveFontSize(fontSize), fontFamily, ...style },
584
+ children: items.map((item) => {
585
+ const open = openIds.includes(item.id);
586
+ const panelId = `accordion-${item.id}-panel`;
587
+ const buttonId = `accordion-${item.id}-button`;
588
+ return /* @__PURE__ */ jsxs("div", { className: "accordion-item", children: [
589
+ /* @__PURE__ */ jsxs(
590
+ "button",
591
+ {
592
+ id: buttonId,
593
+ type: "button",
594
+ className: "accordion-trigger",
595
+ "aria-expanded": open,
596
+ "aria-controls": panelId,
597
+ style: accent ? { color: accent } : void 0,
598
+ onClick: () => toggle(item.id),
599
+ children: [
600
+ /* @__PURE__ */ jsx("span", { children: item.title }),
601
+ /* @__PURE__ */ jsx("span", { className: "accordion-chevron", "data-open": open ? "true" : "false", "aria-hidden": "true" })
602
+ ]
603
+ }
604
+ ),
605
+ open ? /* @__PURE__ */ jsx("div", { id: panelId, role: "region", "aria-labelledby": buttonId, className: "accordion-panel", children: item.content }) : null
606
+ ] }, item.id);
607
+ })
608
+ }
609
+ );
610
+ }
611
+
612
+ // src/theme/css-variables.ts
613
+ function themeToCssVars(theme) {
614
+ return {
615
+ "--al-color-primary": theme.colors.primary,
616
+ "--al-color-primary-hover": theme.colors.primaryHover,
617
+ "--al-color-on-primary": theme.colors.onPrimary,
618
+ "--al-color-secondary": theme.colors.secondary,
619
+ "--al-color-on-secondary": theme.colors.onSecondary,
620
+ "--al-color-danger": theme.colors.danger,
621
+ "--al-color-success": theme.colors.success,
622
+ "--al-color-warning": theme.colors.warning,
623
+ "--al-color-text": theme.colors.text,
624
+ "--al-color-text-muted": theme.colors.textMuted,
625
+ "--al-color-surface": theme.colors.surface,
626
+ "--al-color-surface-muted": theme.colors.surfaceMuted,
627
+ "--al-color-border": theme.colors.border,
628
+ "--al-color-focus": theme.colors.focus,
629
+ "--al-font-family": theme.fontFamily,
630
+ "--al-font-size-xs": theme.fontSize.xs,
631
+ "--al-font-size-sm": theme.fontSize.sm,
632
+ "--al-font-size-md": theme.fontSize.md,
633
+ "--al-font-size-lg": theme.fontSize.lg,
634
+ "--al-radius-sm": theme.radius.sm,
635
+ "--al-radius-md": theme.radius.md,
636
+ "--al-radius-lg": theme.radius.lg,
637
+ "--al-space-sm": theme.spacing.sm,
638
+ "--al-space-md": theme.spacing.md,
639
+ "--al-space-lg": theme.spacing.lg
640
+ };
641
+ }
642
+
643
+ // src/theme/default-theme.ts
644
+ var altruistTheme = {
645
+ colors: {
646
+ primary: "#0b6b4f",
647
+ primaryHover: "#095c44",
648
+ onPrimary: "#ffffff",
649
+ secondary: "#1f2937",
650
+ onSecondary: "#ffffff",
651
+ danger: "#b42318",
652
+ success: "#067647",
653
+ warning: "#b54708",
654
+ text: "#1c2430",
655
+ textMuted: "#5c6778",
656
+ surface: "#ffffff",
657
+ surfaceMuted: "#f5f7fa",
658
+ border: "#d8dee8",
659
+ focus: "#0b6b4f"
660
+ },
661
+ fontFamily: '"Segoe UI", "Noto Sans", sans-serif',
662
+ fontSize: {
663
+ xs: "12px",
664
+ sm: "13px",
665
+ md: "14px",
666
+ lg: "16px"
667
+ },
668
+ radius: {
669
+ sm: "6px",
670
+ md: "8px",
671
+ lg: "12px"
672
+ },
673
+ spacing: {
674
+ sm: "8px",
675
+ md: "12px",
676
+ lg: "16px"
677
+ }
678
+ };
679
+
680
+ // src/theme/presets.ts
681
+ var indigoTheme = {
682
+ colors: {
683
+ primary: "#3730a3",
684
+ primaryHover: "#312e81",
685
+ focus: "#3730a3"
686
+ }
687
+ };
688
+ var darkTheme = {
689
+ colors: {
690
+ primary: "#3ddc97",
691
+ primaryHover: "#2fc588",
692
+ onPrimary: "#06281c",
693
+ secondary: "#d1d5db",
694
+ onSecondary: "#111827",
695
+ danger: "#ff8b80",
696
+ success: "#6ee7b7",
697
+ warning: "#fbbf24",
698
+ text: "#e8edf5",
699
+ textMuted: "#a3b0c2",
700
+ surface: "#161b22",
701
+ surfaceMuted: "#0f141b",
702
+ border: "#2d3746",
703
+ focus: "#3ddc97"
704
+ }
705
+ };
706
+ function mergeTheme(base = altruistTheme, override) {
707
+ if (!override) return base;
708
+ return {
709
+ ...base,
710
+ ...override,
711
+ colors: { ...base.colors, ...override.colors },
712
+ fontSize: { ...base.fontSize, ...override.fontSize },
713
+ radius: { ...base.radius, ...override.radius },
714
+ spacing: { ...base.spacing, ...override.spacing }
715
+ };
716
+ }
717
+ function ThemeProvider({ theme, children, className, style }) {
718
+ const merged = mergeTheme(altruistTheme, theme);
719
+ return /* @__PURE__ */ jsx(
720
+ "div",
721
+ {
722
+ className: className ? `al-theme ${className}` : "al-theme",
723
+ style: { ...themeToCssVars(merged), display: "contents", ...style },
724
+ children
725
+ }
726
+ );
727
+ }
728
+
729
+ export { Accordion, Badge, Button, Card, Checkbox, Field, FileInput, FloatingInput, Input, Select, Table, Textarea, ThemeProvider, altruistTheme, darkTheme, indigoTheme, mergeTheme, themeToCssVars };
730
+ //# sourceMappingURL=index.js.map
731
+ //# sourceMappingURL=index.js.map