@nerds-with-charisma/revit-ui 0.2.0 → 0.4.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.
@@ -0,0 +1,861 @@
1
+ // src/native/components/Alert.tsx
2
+ import {
3
+ Text,
4
+ View
5
+ } from "react-native";
6
+
7
+ // src/native/lib/mergeStyles.ts
8
+ var mergeStyles = (...styles) => styles.filter(Boolean);
9
+
10
+ // src/native/theme/tokensToStyles.ts
11
+ import { StyleSheet } from "react-native";
12
+
13
+ // src/native/lib/remToPx.ts
14
+ var remToPx = (value, base = 16) => {
15
+ const parsed = parseFloat(value);
16
+ if (Number.isNaN(parsed)) return base;
17
+ if (value.endsWith("rem")) return parsed * base;
18
+ return parsed;
19
+ };
20
+
21
+ // src/native/theme/tokensToStyles.ts
22
+ var getThemeColors = (tokens, scheme = "light") => scheme === "dark" ? tokens.colorsDark : tokens.colors;
23
+ var withAlpha = (hex, alpha) => {
24
+ const normalized = hex.replace("#", "");
25
+ const value = normalized.length === 3 ? normalized.split("").map((char) => char + char).join("") : normalized.slice(0, 6);
26
+ const r = parseInt(value.slice(0, 2), 16);
27
+ const g = parseInt(value.slice(2, 4), 16);
28
+ const b = parseInt(value.slice(4, 6), 16);
29
+ return `rgba(${r}, ${g}, ${b}, ${alpha})`;
30
+ };
31
+ var buttonSizeStyles = (size) => {
32
+ switch (size) {
33
+ case "sm":
34
+ return { paddingHorizontal: 12, paddingVertical: 6, fontSize: 10 };
35
+ case "lg":
36
+ return { minWidth: 160, paddingHorizontal: 24, paddingVertical: 12, fontSize: 14 };
37
+ case "icon":
38
+ return { width: 36, height: 36, paddingHorizontal: 0, paddingVertical: 0 };
39
+ default:
40
+ return { paddingHorizontal: 16, paddingVertical: 8, fontSize: 12 };
41
+ }
42
+ };
43
+ var getButtonStyles = (colors, tokens, variant = "default", size = "default") => {
44
+ const pillRadius = remToPx(tokens.radius.pill);
45
+ const base = {
46
+ ...buttonSizeStyles(size),
47
+ alignItems: "center",
48
+ justifyContent: "center",
49
+ flexDirection: "row",
50
+ gap: 8,
51
+ borderRadius: size === "icon" ? pillRadius : pillRadius,
52
+ borderWidth: 2,
53
+ fontWeight: "600",
54
+ textTransform: variant === "link" ? "none" : "uppercase",
55
+ letterSpacing: variant === "link" ? 0 : 1.2
56
+ };
57
+ switch (variant) {
58
+ case "secondary":
59
+ return {
60
+ container: {
61
+ ...base,
62
+ backgroundColor: colors.secondary,
63
+ borderColor: colors.secondary
64
+ },
65
+ text: { color: colors.secondaryForeground }
66
+ };
67
+ case "outline":
68
+ return {
69
+ container: {
70
+ ...base,
71
+ backgroundColor: colors.card,
72
+ borderColor: colors.border
73
+ },
74
+ text: { color: colors.cardForeground }
75
+ };
76
+ case "ghost":
77
+ return {
78
+ container: {
79
+ ...base,
80
+ backgroundColor: "transparent",
81
+ borderColor: "transparent",
82
+ borderWidth: 0
83
+ },
84
+ text: { color: colors.foreground }
85
+ };
86
+ case "link":
87
+ return {
88
+ container: {
89
+ ...base,
90
+ backgroundColor: "transparent",
91
+ borderColor: "transparent",
92
+ borderWidth: 0,
93
+ borderRadius: 0,
94
+ paddingHorizontal: 0,
95
+ paddingVertical: 0
96
+ },
97
+ text: { color: colors.primary, textDecorationLine: "underline" }
98
+ };
99
+ case "destructive":
100
+ return {
101
+ container: {
102
+ ...base,
103
+ backgroundColor: colors.destructive,
104
+ borderColor: colors.destructive
105
+ },
106
+ text: { color: colors.destructiveForeground }
107
+ };
108
+ }
109
+ return {
110
+ container: {
111
+ ...base,
112
+ backgroundColor: colors.primary,
113
+ borderColor: colors.primary,
114
+ shadowColor: "#000000",
115
+ shadowOffset: { width: 0, height: 8 },
116
+ shadowOpacity: 0.07,
117
+ shadowRadius: 12,
118
+ elevation: 4
119
+ },
120
+ text: { color: colors.primaryForeground }
121
+ };
122
+ };
123
+ var getInputStyles = (colors, tokens, variant = "default", size = "default") => {
124
+ const radius = variant === "pill" ? remToPx(tokens.radius.pill) : remToPx(tokens.radius.md);
125
+ const sizeStyles = size === "sm" ? { height: 36, paddingHorizontal: 12, paddingVertical: 4, fontSize: 14 } : size === "md" ? { height: 44, paddingHorizontal: 16, paddingVertical: 8, fontSize: 16 } : { height: 48, paddingHorizontal: 20, paddingVertical: 12, fontSize: 16 };
126
+ return {
127
+ ...sizeStyles,
128
+ width: "100%",
129
+ borderWidth: 1,
130
+ borderColor: colors.border,
131
+ backgroundColor: variant === "filled" ? colors.muted : colors.card,
132
+ color: colors.foreground,
133
+ borderRadius: radius
134
+ };
135
+ };
136
+ var getCardStyles = (colors, tokens, variant = "default") => {
137
+ switch (variant) {
138
+ case "elevated":
139
+ return {
140
+ backgroundColor: colors.card,
141
+ borderRadius: remToPx(tokens.radius.xl),
142
+ shadowColor: "#000000",
143
+ shadowOffset: { width: 0, height: 24 },
144
+ shadowOpacity: 0.12,
145
+ shadowRadius: 48,
146
+ elevation: 8
147
+ };
148
+ case "frost":
149
+ return {
150
+ backgroundColor: withAlpha(colors.card, 0.85),
151
+ borderRadius: remToPx(tokens.radius.lg),
152
+ borderWidth: 1,
153
+ borderColor: withAlpha("#ffffff", 0.55)
154
+ };
155
+ case "outline":
156
+ return {
157
+ backgroundColor: "transparent",
158
+ borderRadius: remToPx(tokens.radius.lg),
159
+ borderWidth: 1,
160
+ borderColor: colors.border
161
+ };
162
+ default:
163
+ return {
164
+ backgroundColor: colors.card,
165
+ borderRadius: remToPx(tokens.radius.lg),
166
+ borderWidth: 1,
167
+ borderColor: colors.border,
168
+ shadowColor: "#000000",
169
+ shadowOffset: { width: 0, height: 18 },
170
+ shadowOpacity: 0.04,
171
+ shadowRadius: 40,
172
+ elevation: 3
173
+ };
174
+ }
175
+ };
176
+ var getCardPadding = (size = "default") => {
177
+ switch (size) {
178
+ case "sm":
179
+ return 16;
180
+ case "lg":
181
+ return 32;
182
+ default:
183
+ return 24;
184
+ }
185
+ };
186
+ var getAlertStyles = (colors, tokens, variant = "default") => {
187
+ const base = {
188
+ width: "100%",
189
+ borderRadius: remToPx(tokens.radius.lg),
190
+ borderWidth: 1,
191
+ paddingHorizontal: 16,
192
+ paddingVertical: 12
193
+ };
194
+ switch (variant) {
195
+ case "warning":
196
+ return {
197
+ ...base,
198
+ borderColor: withAlpha(colors.primary, 0.6),
199
+ backgroundColor: withAlpha(colors.primary, 0.15)
200
+ };
201
+ case "destructive":
202
+ return {
203
+ ...base,
204
+ borderColor: withAlpha(colors.destructive, 0.4),
205
+ backgroundColor: withAlpha(colors.destructive, 0.1)
206
+ };
207
+ default:
208
+ return {
209
+ ...base,
210
+ borderColor: colors.border,
211
+ backgroundColor: colors.card
212
+ };
213
+ }
214
+ };
215
+ var getLabelStyles = (colors, variant = "default") => {
216
+ if (variant === "eyebrow") {
217
+ return {
218
+ fontSize: 12,
219
+ fontWeight: "700",
220
+ textTransform: "uppercase",
221
+ letterSpacing: 3.5,
222
+ color: colors.brand.gold
223
+ };
224
+ }
225
+ return {
226
+ fontSize: 14,
227
+ fontWeight: "500",
228
+ lineHeight: 14,
229
+ color: colors.foreground
230
+ };
231
+ };
232
+ var getHeadingStyles = (colors, variant = "title") => {
233
+ switch (variant) {
234
+ case "page":
235
+ return { fontSize: 24, fontWeight: "600", letterSpacing: -0.5, color: colors.foreground };
236
+ case "section":
237
+ return { fontSize: 18, fontWeight: "600", letterSpacing: -0.25, color: colors.foreground };
238
+ case "eyebrow":
239
+ return {
240
+ fontSize: 12,
241
+ fontWeight: "700",
242
+ textTransform: "uppercase",
243
+ letterSpacing: 3.5,
244
+ color: colors.brand.gold
245
+ };
246
+ case "subtitle":
247
+ return { fontSize: 14, fontWeight: "400", color: colors.mutedForeground };
248
+ default:
249
+ return {
250
+ fontSize: 20,
251
+ fontWeight: "600",
252
+ lineHeight: 20,
253
+ letterSpacing: -0.25,
254
+ color: colors.foreground
255
+ };
256
+ }
257
+ };
258
+ var getTextStyles = (colors, variant = "body") => {
259
+ switch (variant) {
260
+ case "sm":
261
+ return { fontSize: 14, fontWeight: "400", color: colors.foreground };
262
+ case "muted":
263
+ return { fontSize: 14, fontWeight: "400", color: colors.mutedForeground };
264
+ case "lead":
265
+ return { fontSize: 18, fontWeight: "400", color: colors.foreground };
266
+ case "label":
267
+ return { fontSize: 14, fontWeight: "500", lineHeight: 14, color: colors.foreground };
268
+ case "destructive":
269
+ return { fontSize: 14, fontWeight: "400", color: colors.destructive };
270
+ default:
271
+ return { fontSize: 16, fontWeight: "400", color: colors.foreground };
272
+ }
273
+ };
274
+ var getTabsListStyles = (colors, tokens) => ({
275
+ flexDirection: "row",
276
+ alignItems: "center",
277
+ gap: 4,
278
+ borderRadius: remToPx(tokens.radius.pill),
279
+ borderWidth: 1,
280
+ borderColor: colors.border,
281
+ backgroundColor: colors.card,
282
+ padding: 4
283
+ });
284
+ var getTabsTriggerStyles = (colors, tokens, isActive) => ({
285
+ container: {
286
+ alignItems: "center",
287
+ justifyContent: "center",
288
+ borderRadius: remToPx(tokens.radius.pill),
289
+ paddingHorizontal: 16,
290
+ paddingVertical: 8,
291
+ backgroundColor: isActive ? colors.primary : "transparent"
292
+ },
293
+ text: {
294
+ fontSize: 11,
295
+ fontWeight: "600",
296
+ textTransform: "uppercase",
297
+ letterSpacing: 1.2,
298
+ color: isActive ? colors.primaryForeground : colors.foreground
299
+ }
300
+ });
301
+ var tokensToStyleSheet = (tokens, scheme = "light") => {
302
+ const colors = getThemeColors(tokens, scheme);
303
+ return StyleSheet.create({
304
+ screen: {
305
+ flex: 1,
306
+ backgroundColor: colors.background
307
+ },
308
+ foregroundText: {
309
+ color: colors.foreground
310
+ },
311
+ mutedText: {
312
+ color: colors.mutedForeground
313
+ },
314
+ destructiveText: {
315
+ color: colors.destructive
316
+ },
317
+ card: getCardStyles(colors, tokens, "default"),
318
+ cardElevated: getCardStyles(colors, tokens, "elevated"),
319
+ input: getInputStyles(colors, tokens),
320
+ button: getButtonStyles(colors, tokens).container,
321
+ buttonText: getButtonStyles(colors, tokens).text,
322
+ alert: getAlertStyles(colors, tokens),
323
+ tabsList: getTabsListStyles(colors, tokens)
324
+ });
325
+ };
326
+
327
+ // src/native/theme/useRevitTheme.tsx
328
+ import { createContext, useContext, useMemo } from "react";
329
+
330
+ // src/theme/tokens.revit.ts
331
+ var brand = {
332
+ yellow: "#FFE500",
333
+ yellowLight: "#FFF06E",
334
+ offBlack: "#2C2C2C",
335
+ pink: "#FF005C",
336
+ purple: "#BA00FF",
337
+ blue: "#00FFFB",
338
+ gold: "#B8A500",
339
+ brown: "#78350F",
340
+ umber: "#58483B",
341
+ mist: "#F2F2F7"
342
+ };
343
+ var light = {
344
+ background: "#ffffff",
345
+ foreground: brand.offBlack,
346
+ card: "#ffffff",
347
+ cardForeground: brand.offBlack,
348
+ popover: "#ffffff",
349
+ popoverForeground: brand.offBlack,
350
+ primary: brand.yellow,
351
+ primaryForeground: "#000000",
352
+ secondary: "#000000",
353
+ secondaryForeground: "#ffffff",
354
+ muted: brand.mist,
355
+ mutedForeground: brand.umber,
356
+ accent: brand.yellowLight,
357
+ accentForeground: "#000000",
358
+ destructive: "#FF002B",
359
+ destructiveForeground: "#ffffff",
360
+ border: brand.mist,
361
+ input: brand.mist,
362
+ ring: brand.yellow,
363
+ brand
364
+ };
365
+ var dark = {
366
+ background: "#0f172a",
367
+ foreground: "#ffffff",
368
+ card: "#0f172a",
369
+ cardForeground: "#ffffff",
370
+ popover: "#0f172a",
371
+ popoverForeground: "#ffffff",
372
+ primary: brand.yellow,
373
+ primaryForeground: "#000000",
374
+ secondary: brand.yellow,
375
+ secondaryForeground: "#000000",
376
+ muted: "#1e293b",
377
+ mutedForeground: "#cbd5e1",
378
+ accent: "#1e293b",
379
+ accentForeground: "#ffffff",
380
+ destructive: "#FF002B",
381
+ destructiveForeground: "#ffffff",
382
+ border: "#334155",
383
+ input: "#334155",
384
+ ring: brand.yellow,
385
+ brand
386
+ };
387
+ var revitTokens = {
388
+ colors: light,
389
+ colorsDark: dark,
390
+ radius: {
391
+ sm: "0.375rem",
392
+ md: "0.5rem",
393
+ lg: "1.25rem",
394
+ xl: "1.5rem",
395
+ pill: "9999px"
396
+ },
397
+ fontFamily: {
398
+ sans: "Afacad, ui-sans-serif, system-ui, sans-serif"
399
+ }
400
+ };
401
+
402
+ // src/native/theme/useRevitTheme.tsx
403
+ import { jsx } from "react/jsx-runtime";
404
+ var RevitThemeContext = createContext(null);
405
+ var RevitThemeProvider = ({
406
+ children,
407
+ tokens = revitTokens,
408
+ scheme = "light"
409
+ }) => {
410
+ const value = useMemo(
411
+ () => ({
412
+ tokens,
413
+ scheme,
414
+ colors: getThemeColors(tokens, scheme),
415
+ styles: tokensToStyleSheet(tokens, scheme)
416
+ }),
417
+ [tokens, scheme]
418
+ );
419
+ return /* @__PURE__ */ jsx(RevitThemeContext.Provider, { value, children });
420
+ };
421
+ var useRevitTheme = () => {
422
+ const context = useContext(RevitThemeContext);
423
+ if (!context) {
424
+ return {
425
+ tokens: revitTokens,
426
+ scheme: "light",
427
+ colors: getThemeColors(revitTokens, "light"),
428
+ styles: tokensToStyleSheet(revitTokens, "light")
429
+ };
430
+ }
431
+ return context;
432
+ };
433
+
434
+ // src/native/components/Alert.tsx
435
+ import { jsx as jsx2, jsxs } from "react/jsx-runtime";
436
+ var Alert = ({
437
+ variant = "default",
438
+ icon,
439
+ style,
440
+ testID = "Alert",
441
+ children,
442
+ ...props
443
+ }) => {
444
+ const { tokens, colors } = useRevitTheme();
445
+ const alertColor = variant === "destructive" ? colors.destructive : variant === "warning" ? colors.foreground : colors.cardForeground;
446
+ return /* @__PURE__ */ jsxs(
447
+ View,
448
+ {
449
+ testID,
450
+ accessibilityRole: "alert",
451
+ style: mergeStyles(
452
+ getAlertStyles(colors, tokens, variant),
453
+ icon ? { flexDirection: "row", alignItems: "flex-start", gap: 12 } : void 0,
454
+ style
455
+ ),
456
+ ...props,
457
+ children: [
458
+ icon ? /* @__PURE__ */ jsx2(View, { style: { marginTop: 2 }, children: icon }) : null,
459
+ /* @__PURE__ */ jsx2(View, { style: { flex: 1, gap: 4 }, children: typeof children === "string" ? /* @__PURE__ */ jsx2(Text, { style: { fontSize: 14, color: alertColor }, children }) : children })
460
+ ]
461
+ }
462
+ );
463
+ };
464
+ var AlertTitle = ({ style, testID = "AlertTitle", ...props }) => {
465
+ const { colors } = useRevitTheme();
466
+ return /* @__PURE__ */ jsx2(
467
+ Text,
468
+ {
469
+ testID,
470
+ accessibilityRole: "header",
471
+ style: mergeStyles(
472
+ {
473
+ marginBottom: 4,
474
+ fontSize: 14,
475
+ fontWeight: "600",
476
+ letterSpacing: -0.15,
477
+ color: colors.foreground
478
+ },
479
+ style
480
+ ),
481
+ ...props
482
+ }
483
+ );
484
+ };
485
+ var AlertDescription = ({
486
+ style,
487
+ testID = "AlertDescription",
488
+ ...props
489
+ }) => {
490
+ const { colors } = useRevitTheme();
491
+ return /* @__PURE__ */ jsx2(
492
+ Text,
493
+ {
494
+ testID,
495
+ style: mergeStyles({ fontSize: 14, color: colors.mutedForeground }, style),
496
+ ...props
497
+ }
498
+ );
499
+ };
500
+
501
+ // src/native/components/Button.tsx
502
+ import {
503
+ ActivityIndicator,
504
+ Pressable,
505
+ Text as Text2
506
+ } from "react-native";
507
+ import { jsx as jsx3 } from "react/jsx-runtime";
508
+ var Button = ({
509
+ variant = "default",
510
+ size = "default",
511
+ loading = false,
512
+ disabled,
513
+ children,
514
+ style,
515
+ textStyle,
516
+ testID = "Button",
517
+ ...props
518
+ }) => {
519
+ const { tokens, colors } = useRevitTheme();
520
+ const styles = getButtonStyles(colors, tokens, variant, size);
521
+ const isDisabled = disabled || loading;
522
+ return /* @__PURE__ */ jsx3(
523
+ Pressable,
524
+ {
525
+ testID,
526
+ accessibilityRole: "button",
527
+ disabled: isDisabled,
528
+ style: ({ pressed }) => mergeStyles(
529
+ styles.container,
530
+ isDisabled ? { opacity: 0.5 } : void 0,
531
+ pressed && !isDisabled ? { transform: [{ scale: 1.02 }] } : void 0,
532
+ style
533
+ ),
534
+ ...props,
535
+ children: loading ? /* @__PURE__ */ jsx3(ActivityIndicator, { color: styles.text.color, size: "small" }) : typeof children === "string" ? /* @__PURE__ */ jsx3(Text2, { style: mergeStyles(styles.text, textStyle), children }) : children
536
+ }
537
+ );
538
+ };
539
+
540
+ // src/native/components/Card.tsx
541
+ import {
542
+ Text as Text3,
543
+ View as View2
544
+ } from "react-native";
545
+ import { jsx as jsx4 } from "react/jsx-runtime";
546
+ var Card = ({
547
+ variant = "default",
548
+ size: _size = "default",
549
+ style,
550
+ testID = "Card",
551
+ ...props
552
+ }) => {
553
+ const { tokens, colors } = useRevitTheme();
554
+ return /* @__PURE__ */ jsx4(
555
+ View2,
556
+ {
557
+ testID,
558
+ style: mergeStyles(getCardStyles(colors, tokens, variant), style),
559
+ ...props
560
+ }
561
+ );
562
+ };
563
+ var CardHeader = ({
564
+ size = "default",
565
+ style,
566
+ testID = "CardHeader",
567
+ ...props
568
+ }) => {
569
+ const padding = getCardPadding(size);
570
+ return /* @__PURE__ */ jsx4(
571
+ View2,
572
+ {
573
+ testID,
574
+ style: mergeStyles({ flexDirection: "column", gap: 6, padding }, style),
575
+ ...props
576
+ }
577
+ );
578
+ };
579
+ var CardTitle = ({ style, testID = "CardTitle", ...props }) => {
580
+ const { colors } = useRevitTheme();
581
+ return /* @__PURE__ */ jsx4(
582
+ Text3,
583
+ {
584
+ testID,
585
+ accessibilityRole: "header",
586
+ style: mergeStyles(
587
+ {
588
+ fontSize: 20,
589
+ fontWeight: "600",
590
+ lineHeight: 20,
591
+ letterSpacing: -0.25,
592
+ color: colors.foreground
593
+ },
594
+ style
595
+ ),
596
+ ...props
597
+ }
598
+ );
599
+ };
600
+ var CardDescription = ({
601
+ style,
602
+ testID = "CardDescription",
603
+ ...props
604
+ }) => {
605
+ const { colors } = useRevitTheme();
606
+ return /* @__PURE__ */ jsx4(
607
+ Text3,
608
+ {
609
+ testID,
610
+ style: mergeStyles({ fontSize: 14, color: colors.mutedForeground }, style),
611
+ ...props
612
+ }
613
+ );
614
+ };
615
+ var CardContent = ({
616
+ size = "default",
617
+ style,
618
+ testID = "CardContent",
619
+ ...props
620
+ }) => {
621
+ const padding = getCardPadding(size);
622
+ return /* @__PURE__ */ jsx4(
623
+ View2,
624
+ {
625
+ testID,
626
+ style: mergeStyles({ paddingHorizontal: padding, paddingBottom: padding }, style),
627
+ ...props
628
+ }
629
+ );
630
+ };
631
+
632
+ // src/native/components/Heading.tsx
633
+ import { Text as Text4 } from "react-native";
634
+ import { jsx as jsx5 } from "react/jsx-runtime";
635
+ var accessibilityLevels = {
636
+ h1: "header",
637
+ h2: "header",
638
+ h3: "header",
639
+ h4: "header",
640
+ h5: "header",
641
+ h6: "header",
642
+ p: "text"
643
+ };
644
+ var defaultTag = {
645
+ page: "h1",
646
+ title: "h2",
647
+ section: "h3",
648
+ eyebrow: "h2",
649
+ subtitle: "p"
650
+ };
651
+ var Heading = ({
652
+ as,
653
+ variant = "title",
654
+ style,
655
+ testID = "Heading",
656
+ ...props
657
+ }) => {
658
+ const { colors } = useRevitTheme();
659
+ const tag = as ?? defaultTag[variant];
660
+ return /* @__PURE__ */ jsx5(
661
+ Text4,
662
+ {
663
+ testID,
664
+ accessibilityRole: accessibilityLevels[tag],
665
+ style: mergeStyles(getHeadingStyles(colors, variant), style),
666
+ ...props
667
+ }
668
+ );
669
+ };
670
+
671
+ // src/native/components/Input.tsx
672
+ import { TextInput } from "react-native";
673
+ import { jsx as jsx6 } from "react/jsx-runtime";
674
+ var Input = ({
675
+ variant = "default",
676
+ size = "default",
677
+ editable = true,
678
+ style,
679
+ placeholderTextColor,
680
+ testID = "Input",
681
+ ...props
682
+ }) => {
683
+ const { tokens, colors } = useRevitTheme();
684
+ const inputStyles = getInputStyles(colors, tokens, variant, size);
685
+ return /* @__PURE__ */ jsx6(
686
+ TextInput,
687
+ {
688
+ testID,
689
+ editable,
690
+ placeholderTextColor: placeholderTextColor ?? colors.mutedForeground,
691
+ style: mergeStyles(
692
+ inputStyles,
693
+ !editable ? { opacity: 0.5 } : void 0,
694
+ style
695
+ ),
696
+ ...props
697
+ }
698
+ );
699
+ };
700
+
701
+ // src/native/components/Label.tsx
702
+ import { Text as Text5 } from "react-native";
703
+ import { jsx as jsx7 } from "react/jsx-runtime";
704
+ var Label = ({
705
+ variant = "default",
706
+ style,
707
+ testID = "Label",
708
+ ...props
709
+ }) => {
710
+ const { colors } = useRevitTheme();
711
+ return /* @__PURE__ */ jsx7(
712
+ Text5,
713
+ {
714
+ testID,
715
+ accessibilityRole: "text",
716
+ style: mergeStyles(getLabelStyles(colors, variant), style),
717
+ ...props
718
+ }
719
+ );
720
+ };
721
+
722
+ // src/native/components/Tabs.tsx
723
+ import {
724
+ createContext as createContext2,
725
+ useContext as useContext2,
726
+ useMemo as useMemo2,
727
+ useState
728
+ } from "react";
729
+ import {
730
+ Pressable as Pressable2,
731
+ Text as Text6,
732
+ View as View3
733
+ } from "react-native";
734
+ import { jsx as jsx8 } from "react/jsx-runtime";
735
+ var TabsContext = createContext2(null);
736
+ var useTabsContext = () => {
737
+ const context = useContext2(TabsContext);
738
+ if (!context) {
739
+ throw new Error("Tabs components must be used within Tabs");
740
+ }
741
+ return context;
742
+ };
743
+ var Tabs = ({
744
+ value,
745
+ defaultValue = "",
746
+ onValueChange,
747
+ children,
748
+ testID = "Tabs"
749
+ }) => {
750
+ const [internalValue, internalValueSetter] = useState(defaultValue);
751
+ const currentValue = value ?? internalValue;
752
+ const contextValue = useMemo2(
753
+ () => ({
754
+ value: currentValue,
755
+ onValueChange: (nextValue) => {
756
+ if (value === void 0) {
757
+ internalValueSetter(nextValue);
758
+ }
759
+ onValueChange?.(nextValue);
760
+ }
761
+ }),
762
+ [currentValue, onValueChange, value]
763
+ );
764
+ return /* @__PURE__ */ jsx8(TabsContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx8(View3, { testID, children }) });
765
+ };
766
+ var TabsList = ({ style, testID = "TabsList", ...props }) => {
767
+ const { tokens, colors } = useRevitTheme();
768
+ return /* @__PURE__ */ jsx8(
769
+ View3,
770
+ {
771
+ testID,
772
+ style: mergeStyles(getTabsListStyles(colors, tokens), style),
773
+ ...props
774
+ }
775
+ );
776
+ };
777
+ var TabsTrigger = ({
778
+ value,
779
+ disabled,
780
+ children,
781
+ style,
782
+ textStyle,
783
+ testID = "TabsTrigger",
784
+ ...props
785
+ }) => {
786
+ const { tokens, colors } = useRevitTheme();
787
+ const { value: activeValue, onValueChange } = useTabsContext();
788
+ const isActive = activeValue === value;
789
+ const styles = getTabsTriggerStyles(colors, tokens, isActive);
790
+ return /* @__PURE__ */ jsx8(
791
+ Pressable2,
792
+ {
793
+ testID,
794
+ accessibilityRole: "tab",
795
+ accessibilityState: { selected: isActive, disabled: Boolean(disabled) },
796
+ disabled,
797
+ onPress: () => onValueChange(value),
798
+ style: ({ pressed }) => mergeStyles(
799
+ styles.container,
800
+ pressed && !disabled ? { opacity: 0.9 } : void 0,
801
+ disabled ? { opacity: 0.5 } : void 0,
802
+ style
803
+ ),
804
+ ...props,
805
+ children: typeof children === "string" ? /* @__PURE__ */ jsx8(Text6, { style: mergeStyles(styles.text, textStyle), children }) : children
806
+ }
807
+ );
808
+ };
809
+
810
+ // src/native/components/Text.tsx
811
+ import { Text as RNText } from "react-native";
812
+ import { jsx as jsx9 } from "react/jsx-runtime";
813
+ var Text7 = ({
814
+ variant = "body",
815
+ style,
816
+ testID = "Text",
817
+ ...props
818
+ }) => {
819
+ const { colors } = useRevitTheme();
820
+ return /* @__PURE__ */ jsx9(
821
+ RNText,
822
+ {
823
+ testID,
824
+ style: mergeStyles(getTextStyles(colors, variant), style),
825
+ ...props
826
+ }
827
+ );
828
+ };
829
+ export {
830
+ Alert,
831
+ AlertDescription,
832
+ AlertTitle,
833
+ Button,
834
+ Card,
835
+ CardContent,
836
+ CardDescription,
837
+ CardHeader,
838
+ CardTitle,
839
+ Heading,
840
+ Input,
841
+ Label,
842
+ RevitThemeProvider,
843
+ Tabs,
844
+ TabsList,
845
+ TabsTrigger,
846
+ Text7 as Text,
847
+ getAlertStyles,
848
+ getButtonStyles,
849
+ getCardPadding,
850
+ getCardStyles,
851
+ getHeadingStyles,
852
+ getInputStyles,
853
+ getLabelStyles,
854
+ getTabsListStyles,
855
+ getTabsTriggerStyles,
856
+ getTextStyles,
857
+ getThemeColors,
858
+ tokensToStyleSheet,
859
+ useRevitTheme
860
+ };
861
+ //# sourceMappingURL=index.js.map