@nwartz/design-system 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.mjs ADDED
@@ -0,0 +1,2549 @@
1
+ // tokens/colors.ts
2
+ var darkColors = {
3
+ /** App background — the deepest layer. */
4
+ backgroundScreen: "#131313",
5
+ /** Raised surfaces (cards, sheets, modals). */
6
+ shapePrimary: "#1A1A1A",
7
+ /** Inset surfaces, secondary containers, chips. */
8
+ shapeSecondary: "#2D2D2D",
9
+ /** Borders, dividers, disabled outlines. */
10
+ shapeTertiary: "#404040",
11
+ /** Primary text on dark backgrounds. */
12
+ textPrimary: "#FFFFFF",
13
+ /** Secondary / muted text. */
14
+ textSecondary: "#E1E1E1",
15
+ /** Tertiary / placeholder text. */
16
+ textTertiary: "#A0A0A0",
17
+ /** Brand primary — neon lime accent. */
18
+ primaryPure: "#CEFE00",
19
+ /** Brand primary — darker shade for hover/pressed. */
20
+ primaryMid: "#87AD00",
21
+ /** Destructive actions. */
22
+ dangerMid: "#BB4355"
23
+ };
24
+ var lightColors = {
25
+ backgroundScreen: "#F6F5F4",
26
+ shapePrimary: "#FAF9F7",
27
+ shapeSecondary: "#E9E8E7",
28
+ shapeTertiary: "#D9D8D7",
29
+ textPrimary: "#141414",
30
+ textSecondary: "#737271",
31
+ textTertiary: "#8E8D8B",
32
+ primaryPure: "#CEFE00",
33
+ primaryMid: "#87AD00",
34
+ dangerMid: "#BB4355"
35
+ };
36
+
37
+ // tokens/typography.ts
38
+ import { Platform } from "react-native";
39
+ var fontFamilyBase = Platform.select({
40
+ ios: "Archivo",
41
+ android: "Archivo",
42
+ default: "Archivo, system-ui, sans-serif"
43
+ });
44
+ var typography = {
45
+ /** 56px / 900 / 1.15 — hero display, stat rings. */
46
+ display: {
47
+ fontFamily: fontFamilyBase,
48
+ fontSize: 56,
49
+ fontWeight: "900",
50
+ lineHeight: 64
51
+ },
52
+ /** 20px / 700 / 1.0 — section headings, card titles. */
53
+ heading: {
54
+ fontFamily: fontFamilyBase,
55
+ fontSize: 20,
56
+ fontWeight: "700",
57
+ lineHeight: 20
58
+ },
59
+ /** 16px / 400 / 1.5 — body copy, list items. */
60
+ body: {
61
+ fontFamily: fontFamilyBase,
62
+ fontSize: 16,
63
+ fontWeight: "400",
64
+ lineHeight: 24
65
+ },
66
+ /** 12px / 400 / 1.5 — captions, helper text, overlines. */
67
+ caption: {
68
+ fontFamily: fontFamilyBase,
69
+ fontSize: 12,
70
+ fontWeight: "400",
71
+ lineHeight: 18
72
+ }
73
+ };
74
+
75
+ // tokens/elevation.ts
76
+ import { Platform as Platform2 } from "react-native";
77
+ function makeElevation(androidElevation, iOSShadow) {
78
+ if (Platform2.OS === "android") {
79
+ return { elevation: androidElevation };
80
+ }
81
+ return {
82
+ shadowColor: "#101828",
83
+ shadowOffset: { width: iOSShadow.offsetX, height: iOSShadow.offsetY },
84
+ shadowOpacity: iOSShadow.opacity,
85
+ shadowRadius: iOSShadow.radius
86
+ };
87
+ }
88
+ var elevation = {
89
+ /** $elevation-level-xs — subtle lift for inline elements. */
90
+ xs: makeElevation(1, { radius: 2, offsetX: 0, offsetY: 1, opacity: 0.05 }),
91
+ /** $elevation-level-sm — cards at rest. */
92
+ sm: makeElevation(2, { radius: 3, offsetX: 0, offsetY: 1, opacity: 0.1 }),
93
+ /** $elevation-level-md — raised panels, dropdowns. */
94
+ md: makeElevation(4, { radius: 8, offsetX: 0, offsetY: 4, opacity: 0.1 }),
95
+ /** $elevation-level-lg — modals, floating sheets. */
96
+ lg: makeElevation(8, { radius: 16, offsetX: 0, offsetY: 12, opacity: 0.08 }),
97
+ /** $elevation-level-xl — bottom sheets, popover menus. */
98
+ xl: makeElevation(12, { radius: 24, offsetX: 0, offsetY: 20, opacity: 0.08 }),
99
+ /** $elevation-level-xxl — full-screen overlays. */
100
+ xxl: makeElevation(16, { radius: 48, offsetX: 0, offsetY: 24, opacity: 0.08 }),
101
+ /** $elevation-level-xxxl — deepest layer. */
102
+ xxxl: makeElevation(24, { radius: 64, offsetX: 0, offsetY: 32, opacity: 0.08 })
103
+ };
104
+
105
+ // tokens/spacing.ts
106
+ var spacing = {
107
+ /** 0px */
108
+ none: 0,
109
+ /** 2px — hairline gaps. */
110
+ xxs: 2,
111
+ /** 4px — tight inset (icon-to-label). */
112
+ xs: 4,
113
+ /** 8px — compact gaps, small padding. */
114
+ sm: 8,
115
+ /** 12px — default inner padding for small controls. */
116
+ md: 12,
117
+ /** 16px — standard card padding, list row gaps. */
118
+ lg: 16,
119
+ /** 20px — generous spacing. */
120
+ xl: 20,
121
+ /** 24px — section gaps, card outer padding. */
122
+ "2xl": 24,
123
+ /** 32px — large section spacing. */
124
+ "3xl": 32,
125
+ /** 40px — page-level horizontal padding. */
126
+ "4xl": 40,
127
+ /** 48px — hero spacing. */
128
+ "5xl": 48,
129
+ /** 64px — page-level vertical spacing. */
130
+ "6xl": 64,
131
+ /** 80px — maximum spacing. */
132
+ "7xl": 80
133
+ };
134
+
135
+ // tokens/radius.ts
136
+ var radius = {
137
+ /** 4px — tiny elements: badges, tags. */
138
+ xs: 4,
139
+ /** 8px — small controls: inputs, chips. */
140
+ sm: 8,
141
+ /** 12px — medium elements: tiles, list rows. */
142
+ md: 12,
143
+ /** 16px — cards, panels. */
144
+ lg: 16,
145
+ /** 24px — large cards, modals. */
146
+ xl: 24,
147
+ /** Full circle / pill shape. */
148
+ full: 9999
149
+ };
150
+
151
+ // tokens/mapping.ts
152
+ var colorMap = {
153
+ background: "backgroundScreen",
154
+ backgroundElement: "shapeSecondary",
155
+ backgroundSelected: "shapeSecondary",
156
+ surfaceLowest: "shapePrimary",
157
+ surfaceHigh: "shapeSecondary",
158
+ outline: "shapeTertiary",
159
+ outlineVariant: "shapeTertiary",
160
+ text: "textPrimary",
161
+ textSecondary: "textSecondary",
162
+ secondary: "textSecondary",
163
+ secondaryContainer: "shapeSecondary",
164
+ onSecondaryContainer: "textSecondary",
165
+ success: "primaryPure",
166
+ danger: "dangerMid",
167
+ info: "textSecondary",
168
+ warning: "textSecondary"
169
+ };
170
+ var spacingMap = {
171
+ 2: "xxs",
172
+ 4: "xs",
173
+ 8: "sm",
174
+ 12: "md",
175
+ 16: "lg",
176
+ 20: "xl",
177
+ 24: "2xl",
178
+ 32: "3xl",
179
+ 40: "4xl",
180
+ 48: "5xl",
181
+ 64: "6xl",
182
+ 80: "7xl"
183
+ };
184
+ var radiusMap = {
185
+ 4: "xs",
186
+ 8: "sm",
187
+ 10: "sm",
188
+ 12: "md",
189
+ 14: "md",
190
+ 16: "lg",
191
+ 24: "xl",
192
+ 32: "xl",
193
+ 9999: "full"
194
+ };
195
+
196
+ // theme/theme.tsx
197
+ import { createContext, useContext, useMemo } from "react";
198
+ import { useColorScheme } from "react-native";
199
+ import { jsx } from "react/jsx-runtime";
200
+ var ThemeContext = createContext(null);
201
+ function ThemeProvider({ children, mode: modeOverride, colors: colorOverrides }) {
202
+ const systemScheme = useColorScheme();
203
+ const mode = modeOverride ?? (systemScheme === "light" ? "light" : "dark");
204
+ const value = useMemo(
205
+ () => ({
206
+ mode,
207
+ isDark: mode === "dark",
208
+ colors: { ...mode === "dark" ? darkColors : lightColors, ...colorOverrides }
209
+ }),
210
+ [mode, colorOverrides]
211
+ );
212
+ return /* @__PURE__ */ jsx(ThemeContext.Provider, { value, children });
213
+ }
214
+ function useTheme() {
215
+ const ctx = useContext(ThemeContext);
216
+ if (!ctx) {
217
+ return { mode: "dark", isDark: true, colors: darkColors };
218
+ }
219
+ return ctx;
220
+ }
221
+
222
+ // components/Box.tsx
223
+ import { View } from "react-native";
224
+ import { jsx as jsx2 } from "react/jsx-runtime";
225
+ function Box({
226
+ bg,
227
+ p,
228
+ px,
229
+ py,
230
+ m,
231
+ mx,
232
+ my,
233
+ rounded,
234
+ elevation: elev,
235
+ direction,
236
+ align,
237
+ justify,
238
+ gap,
239
+ fullWidth,
240
+ fullHeight,
241
+ style,
242
+ children,
243
+ ...rest
244
+ }) {
245
+ const theme = useTheme();
246
+ return /* @__PURE__ */ jsx2(
247
+ View,
248
+ {
249
+ style: [
250
+ bg && { backgroundColor: theme.colors[bg] },
251
+ p !== void 0 && { padding: spacing[p] },
252
+ px !== void 0 && { paddingHorizontal: spacing[px] },
253
+ py !== void 0 && { paddingVertical: spacing[py] },
254
+ m !== void 0 && { margin: spacing[m] },
255
+ mx !== void 0 && { marginHorizontal: spacing[mx] },
256
+ my !== void 0 && { marginVertical: spacing[my] },
257
+ rounded !== void 0 && { borderRadius: radius[rounded] },
258
+ elev !== void 0 && elevation[elev],
259
+ direction !== void 0 && { flexDirection: direction },
260
+ align !== void 0 && { alignItems: align },
261
+ justify !== void 0 && { justifyContent: justify },
262
+ gap !== void 0 && { gap },
263
+ fullWidth && { width: "100%" },
264
+ fullHeight && { height: "100%" },
265
+ style
266
+ ],
267
+ ...rest,
268
+ children
269
+ }
270
+ );
271
+ }
272
+
273
+ // components/Text.tsx
274
+ import { Text as RNText } from "react-native";
275
+ import { jsx as jsx3 } from "react/jsx-runtime";
276
+ function Text({ variant = "body", color = "textPrimary", textStyle, style, children, ...rest }) {
277
+ const theme = useTheme();
278
+ return /* @__PURE__ */ jsx3(
279
+ RNText,
280
+ {
281
+ style: [typography[variant], { color: theme.colors[color] }, textStyle, style],
282
+ ...rest,
283
+ children
284
+ }
285
+ );
286
+ }
287
+
288
+ // components/Card.tsx
289
+ import { StyleSheet, View as View2 } from "react-native";
290
+ import { jsx as jsx4 } from "react/jsx-runtime";
291
+ function Card({
292
+ level = "sm",
293
+ noPadding = false,
294
+ bordered = false,
295
+ radius: radiusToken,
296
+ style,
297
+ children,
298
+ ...rest
299
+ }) {
300
+ const theme = useTheme();
301
+ return /* @__PURE__ */ jsx4(
302
+ View2,
303
+ {
304
+ style: [
305
+ styles.card,
306
+ elevation[level],
307
+ { backgroundColor: theme.colors.shapePrimary },
308
+ radiusToken !== void 0 && { borderRadius: radius[radiusToken] },
309
+ bordered && { borderWidth: 1, borderColor: theme.colors.shapeTertiary },
310
+ !noPadding && { padding: spacing.lg },
311
+ style
312
+ ],
313
+ ...rest,
314
+ children
315
+ }
316
+ );
317
+ }
318
+ var styles = StyleSheet.create({
319
+ card: {
320
+ borderRadius: radius.lg
321
+ }
322
+ });
323
+
324
+ // components/Button.tsx
325
+ import {
326
+ ActivityIndicator,
327
+ Pressable,
328
+ StyleSheet as StyleSheet2,
329
+ View as View3
330
+ } from "react-native";
331
+ import { jsx as jsx5, jsxs } from "react/jsx-runtime";
332
+ function palette(variant, colors, pressed, brandPrimary, brandOnPrimary) {
333
+ const primary = brandPrimary ?? "#3D8BFF";
334
+ const onPrimary = brandOnPrimary ?? "#FFFFFF";
335
+ switch (variant) {
336
+ case "primary":
337
+ return {
338
+ background: pressed ? primary + "CC" : primary,
339
+ border: "transparent",
340
+ label: onPrimary
341
+ };
342
+ case "secondary":
343
+ return {
344
+ background: pressed ? colors.shapeSecondary + "CC" : colors.shapeSecondary,
345
+ border: "transparent",
346
+ label: colors.textPrimary
347
+ };
348
+ case "outline":
349
+ return {
350
+ background: pressed ? colors.shapeSecondary + "33" : "transparent",
351
+ border: colors.shapeSecondary,
352
+ label: colors.textPrimary
353
+ };
354
+ case "danger":
355
+ return {
356
+ background: pressed ? "#FF45451A" : "transparent",
357
+ border: "#FF454566",
358
+ label: "#FF4545"
359
+ };
360
+ case "ghost":
361
+ return {
362
+ background: pressed ? colors.shapeSecondary + "33" : "transparent",
363
+ border: "transparent",
364
+ label: colors.textSecondary
365
+ };
366
+ }
367
+ }
368
+ function Button({
369
+ label,
370
+ variant = "primary",
371
+ loading = false,
372
+ size = "md",
373
+ style,
374
+ disabled,
375
+ ...rest
376
+ }) {
377
+ const theme = useTheme();
378
+ const isDisabled = disabled || loading;
379
+ return /* @__PURE__ */ jsx5(
380
+ Pressable,
381
+ {
382
+ accessibilityRole: "button",
383
+ disabled: isDisabled,
384
+ style: ({ pressed }) => {
385
+ const colors = palette(variant, theme.colors, pressed);
386
+ return [
387
+ styles2.base,
388
+ size === "sm" && styles2.small,
389
+ {
390
+ backgroundColor: colors.background,
391
+ borderColor: colors.border,
392
+ opacity: isDisabled ? 0.5 : 1
393
+ },
394
+ style
395
+ ];
396
+ },
397
+ ...rest,
398
+ children: ({ pressed }) => {
399
+ const colors = palette(variant, theme.colors, pressed);
400
+ return /* @__PURE__ */ jsxs(View3, { style: styles2.row, children: [
401
+ loading ? /* @__PURE__ */ jsx5(ActivityIndicator, { size: "small", color: colors.label }) : null,
402
+ /* @__PURE__ */ jsx5(
403
+ Text,
404
+ {
405
+ variant: "body",
406
+ color: "textPrimary",
407
+ textStyle: [styles2.label, size === "sm" && styles2.labelSmall, { color: colors.label }],
408
+ children: label
409
+ }
410
+ )
411
+ ] });
412
+ }
413
+ }
414
+ );
415
+ }
416
+ var styles2 = StyleSheet2.create({
417
+ base: {
418
+ borderRadius: radius.sm,
419
+ borderWidth: 1,
420
+ paddingVertical: spacing.lg,
421
+ paddingHorizontal: spacing["2xl"],
422
+ alignItems: "center",
423
+ justifyContent: "center"
424
+ },
425
+ small: {
426
+ paddingVertical: spacing.sm + spacing.xxs,
427
+ paddingHorizontal: spacing.lg
428
+ },
429
+ row: {
430
+ flexDirection: "row",
431
+ alignItems: "center",
432
+ justifyContent: "center",
433
+ gap: spacing.sm
434
+ },
435
+ label: {
436
+ fontSize: 16,
437
+ lineHeight: 24,
438
+ fontWeight: "600"
439
+ },
440
+ labelSmall: {
441
+ fontSize: 14,
442
+ lineHeight: 20
443
+ }
444
+ });
445
+
446
+ // components/Icon.tsx
447
+ import {
448
+ CaretDown as CaretDownIcon,
449
+ CaretUp as CaretUpIcon,
450
+ CaretRight as CaretRightIcon,
451
+ Check as CheckIcon,
452
+ XCircle as XCircleIcon,
453
+ X as XIcon,
454
+ WarningCircle as WarningCircleIcon,
455
+ WarningOctagon as WarningOctagonIcon,
456
+ House as HouseIcon,
457
+ Bell as BellIcon,
458
+ Broadcast as BroadcastIcon,
459
+ ChatCircle as ChatCircleIcon,
460
+ CheckCircle as CheckCircleIcon,
461
+ Truck as TruckIcon,
462
+ CreditCard as CreditCardIcon,
463
+ Crown as CrownIcon,
464
+ CrosshairSimple as CrosshairSimpleIcon,
465
+ Gauge as GaugeIcon,
466
+ Lightning as LightningIcon,
467
+ ThumbsUp as ThumbsUpIcon,
468
+ MapTrifold as MapTrifoldIcon,
469
+ MapPin as MapPinIcon,
470
+ Medal as MedalIcon,
471
+ Microphone as MicrophoneIcon,
472
+ SpeakerSimpleX as SpeakerSimpleXIcon,
473
+ Play as PlayIcon,
474
+ Plus as PlusIcon,
475
+ RadioButton as RadioButtonIcon,
476
+ Radio as RadioIcon,
477
+ ChartBar as ChartBarIcon,
478
+ Receipt as ReceiptIcon,
479
+ PathIcon,
480
+ MagnifyingGlass as MagnifyingGlassIcon,
481
+ GearSix as GearSixIcon,
482
+ ShareNetwork as ShareNetworkIcon,
483
+ Star as StarIcon,
484
+ SignOut as SignOutIcon,
485
+ SteeringWheel as SteeringWheelIcon,
486
+ Timer as TimerIcon,
487
+ Pencil as PencilIcon,
488
+ User as UserIcon,
489
+ UserMinus as UserMinusIcon,
490
+ Users as UsersIcon,
491
+ Globe as GlobeIcon,
492
+ Wallet as WalletIcon,
493
+ Lock as LockIcon
494
+ } from "phosphor-react-native";
495
+ import { jsx as jsx6 } from "react/jsx-runtime";
496
+ var iconMap = {
497
+ "caret-down": CaretDownIcon,
498
+ "caret-up": CaretUpIcon,
499
+ "caret-right": CaretRightIcon,
500
+ check: CheckIcon,
501
+ "x-circle": XCircleIcon,
502
+ x: XIcon,
503
+ "warning-circle": WarningCircleIcon,
504
+ "warning-octagon": WarningOctagonIcon,
505
+ house: HouseIcon,
506
+ bell: BellIcon,
507
+ broadcast: BroadcastIcon,
508
+ "chat-circle": ChatCircleIcon,
509
+ "check-circle": CheckCircleIcon,
510
+ truck: TruckIcon,
511
+ "credit-card": CreditCardIcon,
512
+ crown: CrownIcon,
513
+ "crosshair-simple": CrosshairSimpleIcon,
514
+ gauge: GaugeIcon,
515
+ lightning: LightningIcon,
516
+ "thumbs-up": ThumbsUpIcon,
517
+ "map-trifold": MapTrifoldIcon,
518
+ "map-pin": MapPinIcon,
519
+ medal: MedalIcon,
520
+ microphone: MicrophoneIcon,
521
+ "speaker-simple-x": SpeakerSimpleXIcon,
522
+ play: PlayIcon,
523
+ plus: PlusIcon,
524
+ "radio-button": RadioButtonIcon,
525
+ radio: RadioIcon,
526
+ "chart-bar": ChartBarIcon,
527
+ receipt: ReceiptIcon,
528
+ path: PathIcon,
529
+ "magnifying-glass": MagnifyingGlassIcon,
530
+ "gear-six": GearSixIcon,
531
+ "share-network": ShareNetworkIcon,
532
+ star: StarIcon,
533
+ "sign-out": SignOutIcon,
534
+ "steering-wheel": SteeringWheelIcon,
535
+ timer: TimerIcon,
536
+ pencil: PencilIcon,
537
+ user: UserIcon,
538
+ "user-minus": UserMinusIcon,
539
+ users: UsersIcon,
540
+ globe: GlobeIcon,
541
+ wallet: WalletIcon,
542
+ lock: LockIcon
543
+ };
544
+ function Icon({ name, size = 16, color, weight = "regular" }) {
545
+ const IconComponent = iconMap[name];
546
+ if (!IconComponent) {
547
+ return null;
548
+ }
549
+ return /* @__PURE__ */ jsx6(IconComponent, { size, color, weight });
550
+ }
551
+
552
+ // components/DropdownSelect.tsx
553
+ import { useState } from "react";
554
+ import {
555
+ FlatList,
556
+ Pressable as Pressable2,
557
+ StyleSheet as StyleSheet3,
558
+ View as View4
559
+ } from "react-native";
560
+ import { jsx as jsx7, jsxs as jsxs2 } from "react/jsx-runtime";
561
+ function DropdownSelect({
562
+ items,
563
+ value,
564
+ onSelect,
565
+ open = true,
566
+ maxVisible = 5,
567
+ style,
568
+ ...rest
569
+ }) {
570
+ const theme = useTheme();
571
+ const [hoveredKey, setHoveredKey] = useState(null);
572
+ if (!open) return null;
573
+ return /* @__PURE__ */ jsx7(
574
+ View4,
575
+ {
576
+ style: [
577
+ styles3.container,
578
+ {
579
+ backgroundColor: theme.colors.backgroundScreen,
580
+ borderColor: theme.colors.shapeSecondary
581
+ },
582
+ elevation.xl,
583
+ style
584
+ ],
585
+ ...rest,
586
+ children: /* @__PURE__ */ jsx7(
587
+ FlatList,
588
+ {
589
+ data: items,
590
+ keyExtractor: (item) => item.key,
591
+ bounces: false,
592
+ showsVerticalScrollIndicator: items.length > maxVisible,
593
+ nestedScrollEnabled: true,
594
+ renderItem: ({ item }) => {
595
+ const isSelected = item.key === value;
596
+ const isHovered = item.key === hoveredKey;
597
+ const isDisabled = item.disabled;
598
+ let itemBg;
599
+ if (isHovered) {
600
+ itemBg = theme.colors.shapeSecondary;
601
+ } else if (isSelected) {
602
+ itemBg = theme.colors.backgroundScreen;
603
+ } else {
604
+ itemBg = "transparent";
605
+ }
606
+ return /* @__PURE__ */ jsxs2(View4, { children: [
607
+ /* @__PURE__ */ jsxs2(
608
+ Pressable2,
609
+ {
610
+ disabled: isDisabled,
611
+ onPress: () => onSelect?.(item),
612
+ onHoverIn: () => setHoveredKey(item.key),
613
+ onHoverOut: () => setHoveredKey(null),
614
+ style: () => [
615
+ styles3.item,
616
+ { backgroundColor: itemBg },
617
+ isDisabled && styles3.disabled
618
+ ],
619
+ children: [
620
+ /* @__PURE__ */ jsx7(
621
+ Text,
622
+ {
623
+ variant: "body",
624
+ color: "textSecondary",
625
+ textStyle: [
626
+ styles3.itemLabel,
627
+ { color: isDisabled ? theme.colors.textTertiary : theme.colors.textSecondary }
628
+ ],
629
+ children: item.label
630
+ }
631
+ ),
632
+ isSelected && /* @__PURE__ */ jsx7(Icon, { name: "check", size: 16, color: theme.colors.textSecondary })
633
+ ]
634
+ }
635
+ ),
636
+ item.key !== items[items.length - 1]?.key && /* @__PURE__ */ jsx7(
637
+ View4,
638
+ {
639
+ style: [styles3.divider, { backgroundColor: theme.colors.shapePrimary }]
640
+ }
641
+ )
642
+ ] });
643
+ }
644
+ }
645
+ )
646
+ }
647
+ );
648
+ }
649
+ var styles3 = StyleSheet3.create({
650
+ container: {
651
+ borderRadius: radius.sm,
652
+ borderWidth: 1,
653
+ padding: spacing.xs,
654
+ gap: spacing.xxs
655
+ },
656
+ item: {
657
+ flexDirection: "row",
658
+ alignItems: "center",
659
+ justifyContent: "space-between",
660
+ paddingHorizontal: spacing.lg,
661
+ height: 40,
662
+ borderRadius: radius.sm
663
+ },
664
+ disabled: {
665
+ opacity: 0.32
666
+ },
667
+ itemLabel: {
668
+ fontSize: 14,
669
+ lineHeight: 21
670
+ },
671
+ divider: {
672
+ height: 1,
673
+ marginHorizontal: spacing.lg
674
+ }
675
+ });
676
+
677
+ // components/Autocomplete.tsx
678
+ import { useState as useState2 } from "react";
679
+ import {
680
+ Pressable as Pressable3,
681
+ StyleSheet as StyleSheet4,
682
+ TextInput,
683
+ View as View5
684
+ } from "react-native";
685
+ import { jsx as jsx8, jsxs as jsxs3 } from "react/jsx-runtime";
686
+ function Autocomplete({
687
+ label,
688
+ value,
689
+ onChangeText,
690
+ size = "md",
691
+ disabled = false,
692
+ errorMessage,
693
+ items = [],
694
+ selectedItem,
695
+ onSelectItem,
696
+ open = false,
697
+ onToggle,
698
+ placeholder,
699
+ ...rest
700
+ }) {
701
+ const theme = useTheme();
702
+ const [isFocused, setIsFocused] = useState2(false);
703
+ const hasValue = !!value && value.length > 0;
704
+ const showError = !!errorMessage;
705
+ const isOpen = open;
706
+ const inputHeight = size === "sm" ? 40 : 44;
707
+ const paddingHorizontal = size === "sm" ? spacing.md : spacing.lg;
708
+ const getBorderColor = () => {
709
+ if (showError) {
710
+ return theme.colors.dangerMid;
711
+ }
712
+ if (isFocused) {
713
+ return theme.colors.primaryMid;
714
+ }
715
+ return theme.colors.shapeTertiary;
716
+ };
717
+ const getBoxShadow = () => {
718
+ if (isFocused || showError) {
719
+ const focusColor = showError ? theme.colors.dangerMid : "#FFF6D4";
720
+ return {
721
+ shadowColor: focusColor,
722
+ shadowOffset: { width: 0, height: 0 },
723
+ shadowOpacity: 1,
724
+ shadowRadius: 0,
725
+ elevation: 0
726
+ };
727
+ }
728
+ return elevation.xs;
729
+ };
730
+ const inputContainerStyle = [
731
+ styles4.inputContainer,
732
+ {
733
+ height: inputHeight,
734
+ paddingHorizontal,
735
+ backgroundColor: theme.colors.shapePrimary,
736
+ borderColor: getBorderColor(),
737
+ borderWidth: 1,
738
+ borderRadius: radius.sm
739
+ },
740
+ getBoxShadow()
741
+ ];
742
+ return /* @__PURE__ */ jsxs3(View5, { style: [styles4.wrapper, disabled && styles4.disabledWrapper], children: [
743
+ /* @__PURE__ */ jsx8(
744
+ Text,
745
+ {
746
+ variant: "body",
747
+ color: "textSecondary",
748
+ textStyle: styles4.label,
749
+ children: label
750
+ }
751
+ ),
752
+ /* @__PURE__ */ jsxs3(View5, { style: inputContainerStyle, children: [
753
+ /* @__PURE__ */ jsx8(
754
+ TextInput,
755
+ {
756
+ style: [
757
+ styles4.input,
758
+ {
759
+ color: theme.colors.textPrimary,
760
+ fontSize: 14
761
+ },
762
+ disabled && styles4.inputDisabled
763
+ ],
764
+ value,
765
+ onChangeText,
766
+ placeholder,
767
+ placeholderTextColor: theme.colors.textTertiary,
768
+ editable: !disabled,
769
+ onFocus: () => setIsFocused(true),
770
+ onBlur: () => setIsFocused(false),
771
+ ...rest
772
+ }
773
+ ),
774
+ /* @__PURE__ */ jsxs3(View5, { style: styles4.trailingIcons, children: [
775
+ hasValue && !disabled && /* @__PURE__ */ jsx8(
776
+ Pressable3,
777
+ {
778
+ onPress: () => onChangeText?.(""),
779
+ hitSlop: 8,
780
+ style: styles4.iconButton,
781
+ children: /* @__PURE__ */ jsx8(Icon, { name: "x-circle", size: 16, color: theme.colors.textSecondary })
782
+ }
783
+ ),
784
+ /* @__PURE__ */ jsx8(
785
+ Pressable3,
786
+ {
787
+ onPress: onToggle,
788
+ disabled,
789
+ hitSlop: 8,
790
+ style: styles4.iconButton,
791
+ children: /* @__PURE__ */ jsx8(
792
+ Icon,
793
+ {
794
+ name: isOpen ? "caret-up" : "caret-down",
795
+ size: 16,
796
+ color: theme.colors.textTertiary
797
+ }
798
+ )
799
+ }
800
+ )
801
+ ] })
802
+ ] }),
803
+ showError && /* @__PURE__ */ jsxs3(View5, { style: styles4.errorRow, children: [
804
+ /* @__PURE__ */ jsx8(Icon, { name: "warning-circle", size: 16, color: theme.colors.dangerMid }),
805
+ /* @__PURE__ */ jsx8(
806
+ Text,
807
+ {
808
+ variant: "body",
809
+ color: "textSecondary",
810
+ textStyle: [styles4.errorText, { color: theme.colors.textSecondary }],
811
+ children: errorMessage
812
+ }
813
+ )
814
+ ] }),
815
+ isOpen && items.length > 0 && /* @__PURE__ */ jsx8(
816
+ DropdownSelect,
817
+ {
818
+ items,
819
+ value: selectedItem,
820
+ onSelect: (item) => {
821
+ onSelectItem?.(item);
822
+ onToggle?.();
823
+ },
824
+ open: isOpen,
825
+ style: styles4.dropdown
826
+ }
827
+ )
828
+ ] });
829
+ }
830
+ var styles4 = StyleSheet4.create({
831
+ wrapper: {
832
+ gap: spacing.xs
833
+ },
834
+ disabledWrapper: {
835
+ opacity: 0.32
836
+ },
837
+ label: {
838
+ fontSize: 14,
839
+ lineHeight: 21,
840
+ fontWeight: "500"
841
+ },
842
+ inputContainer: {
843
+ flexDirection: "row",
844
+ alignItems: "center",
845
+ gap: spacing.sm
846
+ },
847
+ input: {
848
+ flex: 1,
849
+ paddingVertical: 0,
850
+ includeFontPadding: false,
851
+ fontSize: 14,
852
+ lineHeight: 21
853
+ },
854
+ inputDisabled: {
855
+ opacity: 1
856
+ },
857
+ trailingIcons: {
858
+ flexDirection: "row",
859
+ alignItems: "center",
860
+ gap: spacing.xs
861
+ },
862
+ iconButton: {
863
+ padding: 2
864
+ },
865
+ errorRow: {
866
+ flexDirection: "row",
867
+ alignItems: "center",
868
+ gap: spacing.xs
869
+ },
870
+ errorText: {
871
+ fontSize: 14,
872
+ lineHeight: 21
873
+ },
874
+ dropdown: {
875
+ marginTop: spacing.xxs
876
+ }
877
+ });
878
+
879
+ // components/SegmentedTabs.tsx
880
+ import { Pressable as Pressable4, StyleSheet as StyleSheet5, View as View6 } from "react-native";
881
+ import { jsx as jsx9 } from "react/jsx-runtime";
882
+ function SegmentedTabs({ tabs, activeTabId, onTabChange }) {
883
+ const { colors } = useTheme();
884
+ return /* @__PURE__ */ jsx9(View6, { style: styles5.container, children: tabs.map((tab) => {
885
+ const isActive = tab.id === activeTabId;
886
+ return /* @__PURE__ */ jsx9(
887
+ Pressable4,
888
+ {
889
+ accessibilityRole: "tab",
890
+ accessibilityState: { selected: isActive },
891
+ onPress: () => onTabChange(tab.id),
892
+ style: ({ pressed }) => [
893
+ styles5.tab,
894
+ pressed && styles5.pressed,
895
+ { borderBottomColor: isActive ? colors.primaryPure : colors.shapeTertiary }
896
+ ],
897
+ children: /* @__PURE__ */ jsx9(
898
+ Text,
899
+ {
900
+ variant: "body",
901
+ color: "textPrimary",
902
+ textStyle: [
903
+ styles5.label,
904
+ {
905
+ color: isActive ? colors.primaryPure : colors.textSecondary,
906
+ fontWeight: isActive ? "700" : "400"
907
+ }
908
+ ],
909
+ children: tab.label
910
+ }
911
+ )
912
+ },
913
+ tab.id
914
+ );
915
+ }) });
916
+ }
917
+ var styles5 = StyleSheet5.create({
918
+ container: {
919
+ flexDirection: "row",
920
+ paddingHorizontal: spacing.xs,
921
+ paddingBottom: spacing.xxs
922
+ },
923
+ tab: {
924
+ flex: 1,
925
+ alignItems: "center",
926
+ justifyContent: "center",
927
+ paddingVertical: spacing.xs,
928
+ paddingBottom: spacing.sm,
929
+ borderBottomWidth: 2
930
+ },
931
+ label: {
932
+ fontSize: 16,
933
+ lineHeight: 24
934
+ },
935
+ pressed: {
936
+ opacity: 0.6
937
+ }
938
+ });
939
+
940
+ // components/Badge.tsx
941
+ import { StyleSheet as StyleSheet6, View as View7 } from "react-native";
942
+ import { jsx as jsx10, jsxs as jsxs4 } from "react/jsx-runtime";
943
+ var colorPalette = {
944
+ primary: { stroke: "#cefe00", solidBg: "#f8ffc5", solidText: "#536e00", outlineText: "#cefe00" },
945
+ secondary: { stroke: "#4fa971", solidBg: "#ddfad9", solidText: "#25584d", outlineText: "#25584d" },
946
+ info: { stroke: "#1048d6", solidBg: "#ebf4ff", solidText: "#1048d6", outlineText: "#1048d6" },
947
+ warning: { stroke: "#e3993a", solidBg: "#fef9ec", solidText: "#642000", outlineText: "#e3993a" },
948
+ success: { stroke: "#138135", solidBg: "#f1feeb", solidText: "#05482c", outlineText: "#138135" },
949
+ error: { stroke: "#bb4355", solidBg: "#fdefed", solidText: "#bb4355", outlineText: "#bb4355" },
950
+ gray: { stroke: "#d9d8d7", solidBg: "#e9e8e7", solidText: "#737271", outlineText: "#737271" }
951
+ };
952
+ var sizeStyles = {
953
+ sm: { height: 22, paddingHorizontal: 8, fontSize: 12, lineHeight: 18, iconSize: 12 },
954
+ md: { height: 24, paddingHorizontal: 8, fontSize: 14, lineHeight: 21, iconSize: 14 },
955
+ lg: { height: 28, paddingHorizontal: 12, fontSize: 14, lineHeight: 21, iconSize: 14 }
956
+ };
957
+ function Badge({
958
+ label,
959
+ size = "md",
960
+ color = "gray",
961
+ mode = "solid",
962
+ icon,
963
+ trailingIcon,
964
+ style,
965
+ ...rest
966
+ }) {
967
+ const palette2 = colorPalette[color];
968
+ const s = sizeStyles[size];
969
+ const bgColor = mode === "solid" ? palette2.solidBg : "transparent";
970
+ const textColor = mode === "solid" ? palette2.solidText : palette2.outlineText;
971
+ const borderColor = mode === "outline" ? palette2.stroke : "transparent";
972
+ return /* @__PURE__ */ jsxs4(
973
+ View7,
974
+ {
975
+ style: [
976
+ styles6.badge,
977
+ {
978
+ height: s.height,
979
+ paddingHorizontal: s.paddingHorizontal,
980
+ backgroundColor: bgColor,
981
+ borderColor,
982
+ borderWidth: 1,
983
+ borderRadius: 16
984
+ },
985
+ style
986
+ ],
987
+ ...rest,
988
+ children: [
989
+ icon && /* @__PURE__ */ jsx10(Icon, { name: icon, size: s.iconSize, color: textColor }),
990
+ /* @__PURE__ */ jsx10(
991
+ Text,
992
+ {
993
+ variant: "caption",
994
+ textStyle: [
995
+ styles6.label,
996
+ { color: textColor, fontSize: s.fontSize, lineHeight: s.lineHeight }
997
+ ],
998
+ children: label
999
+ }
1000
+ ),
1001
+ trailingIcon && /* @__PURE__ */ jsx10(Icon, { name: trailingIcon, size: s.iconSize, color: textColor })
1002
+ ]
1003
+ }
1004
+ );
1005
+ }
1006
+ var styles6 = StyleSheet6.create({
1007
+ badge: {
1008
+ alignSelf: "flex-start",
1009
+ flexDirection: "row",
1010
+ alignItems: "center",
1011
+ gap: spacing.xs
1012
+ },
1013
+ label: {
1014
+ fontWeight: "500"
1015
+ }
1016
+ });
1017
+
1018
+ // components/InputField.tsx
1019
+ import { useState as useState3 } from "react";
1020
+ import {
1021
+ Pressable as Pressable5,
1022
+ StyleSheet as StyleSheet7,
1023
+ TextInput as TextInput2,
1024
+ View as View8
1025
+ } from "react-native";
1026
+ import { jsx as jsx11, jsxs as jsxs5 } from "react/jsx-runtime";
1027
+ function InputField({
1028
+ label,
1029
+ value,
1030
+ onChangeText,
1031
+ size = "md",
1032
+ disabled = false,
1033
+ errorMessage,
1034
+ leadingIcon,
1035
+ trailingIcon,
1036
+ onTrailingIconPress,
1037
+ placeholder,
1038
+ secureTextEntry,
1039
+ ...rest
1040
+ }) {
1041
+ const theme = useTheme();
1042
+ const [isFocused, setIsFocused] = useState3(false);
1043
+ const [isHovered, setIsHovered] = useState3(false);
1044
+ const hasValue = !!value && value.length > 0;
1045
+ const showError = !!errorMessage;
1046
+ const inputHeight = size === "sm" ? 40 : 44;
1047
+ const paddingHorizontal = size === "sm" ? 12 : 14;
1048
+ const getBorderColor = () => {
1049
+ if (showError) {
1050
+ return theme.colors.dangerMid;
1051
+ }
1052
+ if (isFocused) {
1053
+ return "#cefe00";
1054
+ }
1055
+ return "#d9d8d7";
1056
+ };
1057
+ const getBoxShadow = () => {
1058
+ if (isFocused) {
1059
+ return {
1060
+ shadowColor: "#fff6d4",
1061
+ shadowOffset: { width: 0, height: 0 },
1062
+ shadowOpacity: 1,
1063
+ shadowRadius: 0,
1064
+ elevation: 0
1065
+ };
1066
+ }
1067
+ return elevation.xs;
1068
+ };
1069
+ const containerStyle = [
1070
+ styles7.container,
1071
+ {
1072
+ height: inputHeight,
1073
+ paddingHorizontal,
1074
+ backgroundColor: isHovered && !isFocused && !showError ? "#e9e8e7" : "#faf9f7",
1075
+ borderColor: getBorderColor(),
1076
+ borderWidth: 1,
1077
+ borderRadius: 12
1078
+ },
1079
+ getBoxShadow()
1080
+ ];
1081
+ return /* @__PURE__ */ jsxs5(View8, { style: [styles7.wrapper, disabled && styles7.disabledWrapper], children: [
1082
+ label && /* @__PURE__ */ jsx11(Text, { variant: "body", textStyle: [styles7.label, { color: "#737271" }], children: label }),
1083
+ /* @__PURE__ */ jsxs5(
1084
+ Pressable5,
1085
+ {
1086
+ disabled,
1087
+ onHoverIn: () => setIsHovered(true),
1088
+ onHoverOut: () => setIsHovered(false),
1089
+ style: containerStyle,
1090
+ children: [
1091
+ leadingIcon && /* @__PURE__ */ jsx11(Icon, { name: leadingIcon, size: 20, color: "#667085" }),
1092
+ /* @__PURE__ */ jsx11(
1093
+ TextInput2,
1094
+ {
1095
+ style: [
1096
+ styles7.input,
1097
+ {
1098
+ color: hasValue ? "#141414" : "#8e8d8b",
1099
+ fontSize: size === "sm" ? 13 : 14
1100
+ },
1101
+ disabled && styles7.inputDisabled
1102
+ ],
1103
+ value,
1104
+ onChangeText,
1105
+ placeholder,
1106
+ placeholderTextColor: "#8e8d8b",
1107
+ editable: !disabled,
1108
+ onFocus: () => setIsFocused(true),
1109
+ onBlur: () => setIsFocused(false),
1110
+ secureTextEntry,
1111
+ ...rest
1112
+ }
1113
+ ),
1114
+ trailingIcon && /* @__PURE__ */ jsx11(
1115
+ Pressable5,
1116
+ {
1117
+ onPress: onTrailingIconPress,
1118
+ disabled: !onTrailingIconPress,
1119
+ hitSlop: 8,
1120
+ style: styles7.iconButton,
1121
+ children: /* @__PURE__ */ jsx11(Icon, { name: trailingIcon, size: 20, color: "#737271" })
1122
+ }
1123
+ )
1124
+ ]
1125
+ }
1126
+ ),
1127
+ showError && /* @__PURE__ */ jsxs5(View8, { style: styles7.errorRow, children: [
1128
+ /* @__PURE__ */ jsx11(Icon, { name: "warning-circle", size: 16, color: theme.colors.dangerMid }),
1129
+ /* @__PURE__ */ jsx11(Text, { variant: "body", textStyle: [styles7.errorText, { color: "#737271" }], children: errorMessage })
1130
+ ] })
1131
+ ] });
1132
+ }
1133
+ var styles7 = StyleSheet7.create({
1134
+ wrapper: {
1135
+ gap: 4
1136
+ },
1137
+ disabledWrapper: {
1138
+ opacity: 0.32
1139
+ },
1140
+ label: {
1141
+ fontSize: 14,
1142
+ lineHeight: 21,
1143
+ fontWeight: "500"
1144
+ },
1145
+ container: {
1146
+ flexDirection: "row",
1147
+ alignItems: "center",
1148
+ gap: 8
1149
+ },
1150
+ input: {
1151
+ flex: 1,
1152
+ paddingVertical: 0,
1153
+ includeFontPadding: false,
1154
+ fontSize: 14,
1155
+ lineHeight: 21
1156
+ },
1157
+ inputDisabled: {
1158
+ opacity: 1
1159
+ },
1160
+ iconButton: {
1161
+ padding: 2
1162
+ },
1163
+ errorRow: {
1164
+ flexDirection: "row",
1165
+ alignItems: "center",
1166
+ gap: spacing.xs
1167
+ },
1168
+ errorText: {
1169
+ fontSize: 14,
1170
+ lineHeight: 21
1171
+ }
1172
+ });
1173
+
1174
+ // components/Tag.tsx
1175
+ import { Pressable as Pressable6, StyleSheet as StyleSheet8, View as View9 } from "react-native";
1176
+ import { jsx as jsx12, jsxs as jsxs6 } from "react/jsx-runtime";
1177
+ var sizeStyles2 = {
1178
+ sm: { height: 24, paddingHorizontal: 8, fontSize: 12, lineHeight: 18, iconSize: 14, closeSize: 14, countFontSize: 12 },
1179
+ md: { height: 24, paddingHorizontal: 9, fontSize: 14, lineHeight: 21, iconSize: 16, closeSize: 16, countFontSize: 12 },
1180
+ lg: { height: 28, paddingHorizontal: 10, fontSize: 14, lineHeight: 21, iconSize: 16, closeSize: 20, countFontSize: 14 }
1181
+ };
1182
+ function Tag({
1183
+ label,
1184
+ size = "md",
1185
+ icon,
1186
+ trailingIcon,
1187
+ count,
1188
+ onPress,
1189
+ onTrailingPress,
1190
+ style,
1191
+ ...rest
1192
+ }) {
1193
+ const s = sizeStyles2[size];
1194
+ const content = /* @__PURE__ */ jsxs6(View9, { style: [styles8.row, { gap: 3 }], children: [
1195
+ icon && /* @__PURE__ */ jsx12(Icon, { name: icon, size: s.iconSize, color: "#737271" }),
1196
+ /* @__PURE__ */ jsx12(
1197
+ Text,
1198
+ {
1199
+ variant: "caption",
1200
+ textStyle: [styles8.label, { color: "#737271", fontSize: s.fontSize, lineHeight: s.lineHeight }],
1201
+ children: label
1202
+ }
1203
+ ),
1204
+ count !== void 0 && /* @__PURE__ */ jsx12(View9, { style: [styles8.countBadge, { backgroundColor: "#e9e8e7" }], children: /* @__PURE__ */ jsx12(
1205
+ Text,
1206
+ {
1207
+ variant: "caption",
1208
+ textStyle: [styles8.countText, { fontSize: s.countFontSize, color: "#737271" }],
1209
+ children: count
1210
+ }
1211
+ ) }),
1212
+ trailingIcon && /* @__PURE__ */ jsx12(
1213
+ Pressable6,
1214
+ {
1215
+ onPress: onTrailingPress,
1216
+ hitSlop: 4,
1217
+ style: styles8.trailingButton,
1218
+ children: /* @__PURE__ */ jsx12(Icon, { name: trailingIcon, size: s.closeSize, color: "#737271" })
1219
+ }
1220
+ )
1221
+ ] });
1222
+ const containerStyle = [
1223
+ styles8.tag,
1224
+ {
1225
+ height: s.height,
1226
+ paddingHorizontal: s.paddingHorizontal,
1227
+ backgroundColor: "#faf9f7",
1228
+ borderColor: "#d9d8d7",
1229
+ borderWidth: 1,
1230
+ borderRadius: 6
1231
+ },
1232
+ style
1233
+ ];
1234
+ if (onPress) {
1235
+ return /* @__PURE__ */ jsx12(Pressable6, { accessibilityRole: "button", onPress, style: containerStyle, ...rest, children: content });
1236
+ }
1237
+ return /* @__PURE__ */ jsx12(View9, { style: containerStyle, ...rest, children: content });
1238
+ }
1239
+ var styles8 = StyleSheet8.create({
1240
+ tag: {
1241
+ alignSelf: "flex-start"
1242
+ },
1243
+ row: {
1244
+ flexDirection: "row",
1245
+ alignItems: "center"
1246
+ },
1247
+ label: {
1248
+ fontWeight: "500"
1249
+ },
1250
+ trailingButton: {
1251
+ padding: 2
1252
+ },
1253
+ countBadge: {
1254
+ borderRadius: 3,
1255
+ paddingHorizontal: 4,
1256
+ paddingVertical: 0,
1257
+ alignItems: "center",
1258
+ justifyContent: "center"
1259
+ },
1260
+ countText: {
1261
+ fontWeight: "500"
1262
+ }
1263
+ });
1264
+
1265
+ // components/Toggle.tsx
1266
+ import { Pressable as Pressable7, StyleSheet as StyleSheet9, View as View10 } from "react-native";
1267
+ import { Fragment, jsx as jsx13, jsxs as jsxs7 } from "react/jsx-runtime";
1268
+ var sizeConfig = {
1269
+ md: { trackWidth: 44, trackHeight: 24, thumbSize: 20, thumbOnX: 22, thumbOffX: 2, gap: 12 },
1270
+ sm: { trackWidth: 36, trackHeight: 20, thumbSize: 16, thumbOnX: 18, thumbOffX: 2, gap: 8 }
1271
+ };
1272
+ function Toggle({ value, onValueChange, label, disabled = false, size = "md" }) {
1273
+ const s = sizeConfig[size];
1274
+ const trackColor = value ? "#cefe00" : "#e9e8e7";
1275
+ const hoverTrackColor = value ? "#87ad00" : "#d9d8d7";
1276
+ return /* @__PURE__ */ jsx13(
1277
+ Pressable7,
1278
+ {
1279
+ accessibilityRole: "switch",
1280
+ accessibilityState: { checked: value, disabled },
1281
+ disabled,
1282
+ onPress: () => onValueChange(!value),
1283
+ style: ({ pressed }) => [
1284
+ styles9.container,
1285
+ { gap: s.gap },
1286
+ pressed && styles9.pressed,
1287
+ disabled && styles9.disabled
1288
+ ],
1289
+ children: ({ pressed }) => /* @__PURE__ */ jsxs7(Fragment, { children: [
1290
+ /* @__PURE__ */ jsx13(
1291
+ View10,
1292
+ {
1293
+ style: [
1294
+ styles9.track,
1295
+ {
1296
+ width: s.trackWidth,
1297
+ height: s.trackHeight,
1298
+ borderRadius: 12,
1299
+ backgroundColor: pressed ? hoverTrackColor : trackColor,
1300
+ justifyContent: value ? "flex-end" : "flex-start",
1301
+ paddingHorizontal: 2
1302
+ }
1303
+ ],
1304
+ children: /* @__PURE__ */ jsx13(
1305
+ View10,
1306
+ {
1307
+ style: [
1308
+ styles9.thumb,
1309
+ {
1310
+ width: s.thumbSize,
1311
+ height: s.thumbSize,
1312
+ borderRadius: s.thumbSize / 2,
1313
+ backgroundColor: "#ffffff",
1314
+ shadowColor: "#101828",
1315
+ shadowOffset: { width: 0, height: 2 },
1316
+ shadowOpacity: 0.16,
1317
+ shadowRadius: 6,
1318
+ elevation: 3
1319
+ }
1320
+ ]
1321
+ }
1322
+ )
1323
+ }
1324
+ ),
1325
+ label && /* @__PURE__ */ jsx13(
1326
+ Text,
1327
+ {
1328
+ variant: "body",
1329
+ textStyle: [styles9.label, { color: "#141414" }],
1330
+ children: label
1331
+ }
1332
+ )
1333
+ ] })
1334
+ }
1335
+ );
1336
+ }
1337
+ var styles9 = StyleSheet9.create({
1338
+ container: {
1339
+ flexDirection: "row",
1340
+ alignItems: "center"
1341
+ },
1342
+ pressed: {
1343
+ opacity: 0.7
1344
+ },
1345
+ disabled: {
1346
+ opacity: 0.32
1347
+ },
1348
+ track: {
1349
+ alignItems: "center",
1350
+ justifyContent: "center"
1351
+ },
1352
+ thumb: {},
1353
+ label: {
1354
+ fontSize: 16,
1355
+ lineHeight: 24,
1356
+ fontWeight: "500"
1357
+ }
1358
+ });
1359
+
1360
+ // components/DatePicker.tsx
1361
+ import { useState as useState4 } from "react";
1362
+ import {
1363
+ Pressable as Pressable8,
1364
+ StyleSheet as StyleSheet10,
1365
+ View as View11
1366
+ } from "react-native";
1367
+ import { jsx as jsx14, jsxs as jsxs8 } from "react/jsx-runtime";
1368
+ var WEEKDAYS = ["Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"];
1369
+ var MONTH_NAMES = [
1370
+ "Janeiro",
1371
+ "Fevereiro",
1372
+ "Mar\xE7o",
1373
+ "Abril",
1374
+ "Maio",
1375
+ "Junho",
1376
+ "Julho",
1377
+ "Agosto",
1378
+ "Setembro",
1379
+ "Outubro",
1380
+ "Novembro",
1381
+ "Dezembro"
1382
+ ];
1383
+ function getDaysInMonth(year, month) {
1384
+ return new Date(year, month + 1, 0).getDate();
1385
+ }
1386
+ function getFirstDayOfMonth(year, month) {
1387
+ const day = new Date(year, month, 1).getDay();
1388
+ return day === 0 ? 6 : day - 1;
1389
+ }
1390
+ function formatDate(date) {
1391
+ const day = date.getDate().toString().padStart(2, "0");
1392
+ const month = (date.getMonth() + 1).toString().padStart(2, "0");
1393
+ const year = date.getFullYear();
1394
+ return `${day}/${month}/${year}`;
1395
+ }
1396
+ function isSameDay(a, b) {
1397
+ return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
1398
+ }
1399
+ function isInRange(date, start, end) {
1400
+ if (!start || !end) {
1401
+ return false;
1402
+ }
1403
+ const time = date.getTime();
1404
+ return time > start.getTime() && time < end.getTime();
1405
+ }
1406
+ function DatePicker({
1407
+ startDate,
1408
+ endDate,
1409
+ onChange,
1410
+ disabled = false,
1411
+ errorMessage,
1412
+ placeholder = "Selecione as datas",
1413
+ open = false,
1414
+ onToggle
1415
+ }) {
1416
+ const [isHovered, setIsHovered] = useState4(false);
1417
+ const [viewYear, setViewYear] = useState4(startDate?.getFullYear() ?? (/* @__PURE__ */ new Date()).getFullYear());
1418
+ const [viewMonth, setViewMonth] = useState4(startDate?.getMonth() ?? (/* @__PURE__ */ new Date()).getMonth());
1419
+ const [selectingEnd, setSelectingEnd] = useState4(false);
1420
+ const showError = !!errorMessage;
1421
+ const today = /* @__PURE__ */ new Date();
1422
+ const navigateMonth = (delta) => {
1423
+ const newDate = new Date(viewYear, viewMonth + delta, 1);
1424
+ setViewYear(newDate.getFullYear());
1425
+ setViewMonth(newDate.getMonth());
1426
+ };
1427
+ const handleDayPress = (day) => {
1428
+ const date = new Date(viewYear, viewMonth, day);
1429
+ if (!selectingEnd) {
1430
+ onChange?.(date, null);
1431
+ setSelectingEnd(true);
1432
+ } else {
1433
+ if (startDate && date < startDate) {
1434
+ onChange?.(date, startDate);
1435
+ } else {
1436
+ onChange?.(startDate ?? date, date);
1437
+ }
1438
+ setSelectingEnd(false);
1439
+ }
1440
+ };
1441
+ const handleCancel = () => {
1442
+ onChange?.(null, null);
1443
+ setSelectingEnd(false);
1444
+ onToggle?.();
1445
+ };
1446
+ const handleApply = () => {
1447
+ onToggle?.();
1448
+ };
1449
+ const daysInMonth = getDaysInMonth(viewYear, viewMonth);
1450
+ const firstDay = getFirstDayOfMonth(viewYear, viewMonth);
1451
+ const triggerStyle = [
1452
+ styles10.trigger,
1453
+ {
1454
+ backgroundColor: "#faf9f7",
1455
+ borderColor: showError ? "#bb4355" : "#d9d8d7",
1456
+ borderWidth: 1,
1457
+ borderRadius: 8
1458
+ },
1459
+ elevation.xs
1460
+ ];
1461
+ return /* @__PURE__ */ jsxs8(View11, { style: styles10.wrapper, children: [
1462
+ /* @__PURE__ */ jsxs8(
1463
+ Pressable8,
1464
+ {
1465
+ disabled,
1466
+ onPress: onToggle,
1467
+ onHoverIn: () => setIsHovered(true),
1468
+ onHoverOut: () => setIsHovered(false),
1469
+ style: [
1470
+ triggerStyle,
1471
+ isHovered && !disabled && { backgroundColor: "#e9e8e7" }
1472
+ ],
1473
+ children: [
1474
+ /* @__PURE__ */ jsx14(Icon, { name: "timer", size: 20, color: "#101828" }),
1475
+ /* @__PURE__ */ jsx14(
1476
+ Text,
1477
+ {
1478
+ variant: "body",
1479
+ textStyle: [
1480
+ styles10.triggerText,
1481
+ {
1482
+ color: startDate ? "#101828" : "#8e8d8b",
1483
+ fontWeight: startDate ? "600" : "400"
1484
+ }
1485
+ ],
1486
+ children: (() => {
1487
+ if (startDate && endDate) {
1488
+ return `${formatDate(startDate)} -- ${formatDate(endDate)}`;
1489
+ }
1490
+ if (startDate) {
1491
+ return `${formatDate(startDate)} --`;
1492
+ }
1493
+ return placeholder;
1494
+ })()
1495
+ }
1496
+ )
1497
+ ]
1498
+ }
1499
+ ),
1500
+ showError && /* @__PURE__ */ jsxs8(View11, { style: styles10.errorRow, children: [
1501
+ /* @__PURE__ */ jsx14(Icon, { name: "warning-circle", size: 16, color: "#bb4355" }),
1502
+ /* @__PURE__ */ jsx14(Text, { variant: "body", textStyle: [styles10.errorText, { color: "#737271" }], children: errorMessage })
1503
+ ] }),
1504
+ open && /* @__PURE__ */ jsxs8(
1505
+ View11,
1506
+ {
1507
+ style: [
1508
+ styles10.calendar,
1509
+ {
1510
+ backgroundColor: "#f6f5f4",
1511
+ borderColor: "#e9e8e7"
1512
+ },
1513
+ elevation.lg
1514
+ ],
1515
+ children: [
1516
+ /* @__PURE__ */ jsxs8(View11, { style: styles10.contentArea, children: [
1517
+ /* @__PURE__ */ jsxs8(View11, { style: styles10.inputRow, children: [
1518
+ /* @__PURE__ */ jsx14(View11, { style: [styles10.dateInput, { borderColor: "#d9d8d7" }], children: /* @__PURE__ */ jsx14(Text, { variant: "body", textStyle: { color: startDate ? "#141414" : "#8e8d8b", fontSize: 14 }, children: startDate ? formatDate(startDate) : "Data inicial" }) }),
1519
+ /* @__PURE__ */ jsx14(Text, { variant: "body", textStyle: { color: "#d9d8d7", fontSize: 16 }, children: "--" }),
1520
+ /* @__PURE__ */ jsx14(View11, { style: [styles10.dateInput, { borderColor: "#d0d5dd" }], children: /* @__PURE__ */ jsx14(Text, { variant: "body", textStyle: { color: endDate ? "#101828" : "#8e8d8b", fontSize: 14 }, children: endDate ? formatDate(endDate) : "Data final" }) })
1521
+ ] }),
1522
+ /* @__PURE__ */ jsxs8(View11, { style: styles10.header, children: [
1523
+ /* @__PURE__ */ jsx14(Pressable8, { onPress: () => navigateMonth(-1), hitSlop: 8, style: styles10.navButton, children: /* @__PURE__ */ jsx14(View11, { style: { transform: [{ rotate: "180deg" }] }, children: /* @__PURE__ */ jsx14(Icon, { name: "caret-right", size: 16, color: "#737271" }) }) }),
1524
+ /* @__PURE__ */ jsxs8(Text, { variant: "body", textStyle: styles10.monthLabel, children: [
1525
+ MONTH_NAMES[viewMonth],
1526
+ " ",
1527
+ viewYear
1528
+ ] }),
1529
+ /* @__PURE__ */ jsx14(Pressable8, { onPress: () => navigateMonth(1), hitSlop: 8, style: styles10.navButton, children: /* @__PURE__ */ jsx14(Icon, { name: "caret-right", size: 16, color: "#737271" }) })
1530
+ ] }),
1531
+ /* @__PURE__ */ jsx14(View11, { style: styles10.weekdayRow, children: WEEKDAYS.map((day) => /* @__PURE__ */ jsx14(Text, { variant: "caption", textStyle: styles10.weekdayText, children: day }, day)) }),
1532
+ /* @__PURE__ */ jsxs8(View11, { style: styles10.daysGrid, children: [
1533
+ Array.from({ length: firstDay }).map((_, i) => /* @__PURE__ */ jsx14(View11, { style: styles10.dayCell }, `empty-${i}`)),
1534
+ Array.from({ length: daysInMonth }).map((_, i) => {
1535
+ const day = i + 1;
1536
+ const date = new Date(viewYear, viewMonth, day);
1537
+ const isStartDate = !!startDate && isSameDay(date, startDate);
1538
+ const isEndDate = !!endDate && isSameDay(date, endDate);
1539
+ const isSelected = isStartDate || isEndDate;
1540
+ const inRange = isInRange(date, startDate ?? null, endDate ?? null);
1541
+ const isTodayDate = isSameDay(date, today);
1542
+ return /* @__PURE__ */ jsx14(
1543
+ Pressable8,
1544
+ {
1545
+ onPress: () => handleDayPress(day),
1546
+ style: [
1547
+ styles10.dayCell,
1548
+ inRange && { backgroundColor: "#d9d8d7" },
1549
+ (isStartDate || !endDate && selectingEnd && startDate && isSameDay(date, startDate)) && {
1550
+ borderRadius: 20,
1551
+ backgroundColor: "#cefe00"
1552
+ },
1553
+ isEndDate && {
1554
+ borderRadius: 20,
1555
+ backgroundColor: "#cefe00"
1556
+ }
1557
+ ],
1558
+ children: /* @__PURE__ */ jsx14(
1559
+ Text,
1560
+ {
1561
+ variant: "caption",
1562
+ textStyle: [
1563
+ styles10.dayText,
1564
+ {
1565
+ color: isSelected ? "#000000" : "#141414",
1566
+ fontWeight: isTodayDate || isSelected ? "500" : "400"
1567
+ }
1568
+ ],
1569
+ children: day
1570
+ }
1571
+ )
1572
+ },
1573
+ day
1574
+ );
1575
+ })
1576
+ ] })
1577
+ ] }),
1578
+ /* @__PURE__ */ jsxs8(View11, { style: styles10.bottomPanel, children: [
1579
+ /* @__PURE__ */ jsx14(
1580
+ Pressable8,
1581
+ {
1582
+ onPress: handleCancel,
1583
+ style: [styles10.actionButton, { borderColor: "#d9d8d7", backgroundColor: "#faf9f7" }],
1584
+ children: /* @__PURE__ */ jsx14(Text, { variant: "body", textStyle: { color: "#101828", fontSize: 14, fontWeight: "600" }, children: "Cancelar" })
1585
+ }
1586
+ ),
1587
+ /* @__PURE__ */ jsx14(
1588
+ Pressable8,
1589
+ {
1590
+ onPress: handleApply,
1591
+ style: [styles10.actionButton, { borderColor: "#cefe00", backgroundColor: "#cefe00" }],
1592
+ children: /* @__PURE__ */ jsx14(Text, { variant: "body", textStyle: { color: "#000000", fontSize: 14, fontWeight: "600" }, children: "Aplicar" })
1593
+ }
1594
+ )
1595
+ ] })
1596
+ ]
1597
+ }
1598
+ )
1599
+ ] });
1600
+ }
1601
+ var styles10 = StyleSheet10.create({
1602
+ wrapper: {
1603
+ gap: spacing.xs
1604
+ },
1605
+ trigger: {
1606
+ flexDirection: "row",
1607
+ alignItems: "center",
1608
+ height: 40,
1609
+ paddingHorizontal: 16,
1610
+ gap: 8
1611
+ },
1612
+ triggerText: {
1613
+ fontSize: 14,
1614
+ lineHeight: 21
1615
+ },
1616
+ errorRow: {
1617
+ flexDirection: "row",
1618
+ alignItems: "center",
1619
+ gap: spacing.xs
1620
+ },
1621
+ errorText: {
1622
+ fontSize: 14,
1623
+ lineHeight: 21
1624
+ },
1625
+ calendar: {
1626
+ borderRadius: 12,
1627
+ borderWidth: 1,
1628
+ overflow: "hidden"
1629
+ },
1630
+ contentArea: {
1631
+ padding: 20,
1632
+ gap: 16
1633
+ },
1634
+ inputRow: {
1635
+ flexDirection: "row",
1636
+ alignItems: "center",
1637
+ gap: 8
1638
+ },
1639
+ dateInput: {
1640
+ flex: 1,
1641
+ height: 44,
1642
+ borderWidth: 1,
1643
+ borderRadius: 12,
1644
+ backgroundColor: "#faf9f7",
1645
+ paddingHorizontal: 14,
1646
+ alignItems: "flex-start",
1647
+ justifyContent: "center"
1648
+ },
1649
+ header: {
1650
+ flexDirection: "row",
1651
+ alignItems: "center",
1652
+ justifyContent: "space-between"
1653
+ },
1654
+ navButton: {
1655
+ width: 36,
1656
+ height: 36,
1657
+ borderRadius: 16,
1658
+ borderWidth: 1,
1659
+ borderColor: "#d9d8d7",
1660
+ alignItems: "center",
1661
+ justifyContent: "center"
1662
+ },
1663
+ monthLabel: {
1664
+ fontSize: 16,
1665
+ fontWeight: "600",
1666
+ lineHeight: 24,
1667
+ color: "#141414"
1668
+ },
1669
+ weekdayRow: {
1670
+ flexDirection: "row"
1671
+ },
1672
+ weekdayText: {
1673
+ flex: 1,
1674
+ textAlign: "center",
1675
+ fontSize: 14,
1676
+ lineHeight: 20,
1677
+ fontWeight: "500",
1678
+ color: "#101828"
1679
+ },
1680
+ daysGrid: {
1681
+ flexDirection: "row",
1682
+ flexWrap: "wrap"
1683
+ },
1684
+ dayCell: {
1685
+ width: "14.28%",
1686
+ aspectRatio: 1,
1687
+ alignItems: "center",
1688
+ justifyContent: "center",
1689
+ borderRadius: 20
1690
+ },
1691
+ dayText: {
1692
+ fontSize: 14,
1693
+ lineHeight: 20
1694
+ },
1695
+ bottomPanel: {
1696
+ flexDirection: "row",
1697
+ padding: 16,
1698
+ gap: 12,
1699
+ borderTopWidth: 1,
1700
+ borderTopColor: "#e9e8e7"
1701
+ },
1702
+ actionButton: {
1703
+ flex: 1,
1704
+ height: 40,
1705
+ borderRadius: 16,
1706
+ borderWidth: 1,
1707
+ alignItems: "center",
1708
+ justifyContent: "center"
1709
+ }
1710
+ });
1711
+
1712
+ // components/Checkbox.tsx
1713
+ import { useState as useState5 } from "react";
1714
+ import { Pressable as Pressable9, StyleSheet as StyleSheet11, View as View12 } from "react-native";
1715
+ import { jsx as jsx15, jsxs as jsxs9 } from "react/jsx-runtime";
1716
+ var sizeConfig2 = {
1717
+ sm: { boxSize: 16, iconSize: 12, gap: 8, fontSize: 14, lineHeight: 20, borderRadius: 4, radioRadius: 8 },
1718
+ md: { boxSize: 20, iconSize: 12, gap: 12, fontSize: 16, lineHeight: 24, borderRadius: 6, radioRadius: 10 }
1719
+ };
1720
+ function Checkbox({
1721
+ value,
1722
+ onValueChange,
1723
+ label,
1724
+ disabled = false,
1725
+ size = "md",
1726
+ type = "checkbox",
1727
+ indeterminate = false
1728
+ }) {
1729
+ const [isHovered, setIsHovered] = useState5(false);
1730
+ const s = sizeConfig2[size];
1731
+ const isChecked = value || indeterminate;
1732
+ const isRadio = type === "radio";
1733
+ const getBoxStyles = () => {
1734
+ if (isRadio) {
1735
+ const br = isChecked ? 500 : s.radioRadius;
1736
+ const borderColor2 = isChecked || isHovered ? "#cefe00" : "#d9d8d7";
1737
+ return {
1738
+ borderRadius: br,
1739
+ backgroundColor: isChecked ? "#cefe00" : "#faf9f7",
1740
+ borderColor: borderColor2
1741
+ };
1742
+ }
1743
+ let bgColor = "#faf9f7";
1744
+ if (isChecked) {
1745
+ bgColor = isHovered ? "#87ad00" : "#cefe00";
1746
+ }
1747
+ let borderColor = "#d9d8d7";
1748
+ if (isChecked) {
1749
+ borderColor = isHovered ? "#87ad00" : "#cefe00";
1750
+ } else if (isHovered) {
1751
+ borderColor = "#cefe00";
1752
+ }
1753
+ return {
1754
+ borderRadius: s.borderRadius,
1755
+ backgroundColor: bgColor,
1756
+ borderColor
1757
+ };
1758
+ };
1759
+ const boxStyles = getBoxStyles();
1760
+ return /* @__PURE__ */ jsxs9(
1761
+ Pressable9,
1762
+ {
1763
+ accessibilityRole: isRadio ? "radio" : "checkbox",
1764
+ accessibilityState: { checked: value, disabled },
1765
+ disabled,
1766
+ onPress: () => onValueChange(!value),
1767
+ onHoverIn: () => setIsHovered(true),
1768
+ onHoverOut: () => setIsHovered(false),
1769
+ style: ({ pressed }) => [
1770
+ styles11.container,
1771
+ { gap: s.gap },
1772
+ pressed && styles11.pressed,
1773
+ disabled && styles11.disabled
1774
+ ],
1775
+ children: [
1776
+ /* @__PURE__ */ jsx15(
1777
+ View12,
1778
+ {
1779
+ style: [
1780
+ styles11.box,
1781
+ {
1782
+ width: s.boxSize,
1783
+ height: s.boxSize,
1784
+ borderWidth: isChecked ? 0 : 1.5,
1785
+ ...boxStyles
1786
+ }
1787
+ ],
1788
+ children: indeterminate ? /* @__PURE__ */ jsx15(View12, { style: [styles11.indeterminateBar, { backgroundColor: "#ffffff" }] }) : isChecked && /* @__PURE__ */ jsx15(Icon, { name: "check", size: s.iconSize, color: "#ffffff", weight: "bold" })
1789
+ }
1790
+ ),
1791
+ label && /* @__PURE__ */ jsx15(
1792
+ Text,
1793
+ {
1794
+ variant: "body",
1795
+ textStyle: [styles11.label, { color: "#141414", fontSize: s.fontSize, lineHeight: s.lineHeight }],
1796
+ children: label
1797
+ }
1798
+ )
1799
+ ]
1800
+ }
1801
+ );
1802
+ }
1803
+ var styles11 = StyleSheet11.create({
1804
+ container: {
1805
+ flexDirection: "row",
1806
+ alignItems: "center"
1807
+ },
1808
+ pressed: {
1809
+ opacity: 0.7
1810
+ },
1811
+ disabled: {
1812
+ opacity: 0.32
1813
+ },
1814
+ box: {
1815
+ alignItems: "center",
1816
+ justifyContent: "center"
1817
+ },
1818
+ indeterminateBar: {
1819
+ width: 10,
1820
+ height: 2,
1821
+ borderRadius: 1
1822
+ },
1823
+ label: {
1824
+ fontWeight: "500"
1825
+ }
1826
+ });
1827
+
1828
+ // components/TablePagination.tsx
1829
+ import { Pressable as Pressable10, StyleSheet as StyleSheet12, View as View13 } from "react-native";
1830
+ import { jsx as jsx16, jsxs as jsxs10 } from "react/jsx-runtime";
1831
+ function getVisiblePages(current, total) {
1832
+ if (total <= 7) {
1833
+ return Array.from({ length: total }, (_, i) => i + 1);
1834
+ }
1835
+ const pages = [1];
1836
+ if (current > 3) {
1837
+ pages.push("ellipsis");
1838
+ }
1839
+ const start = Math.max(2, current - 1);
1840
+ const end = Math.min(total - 1, current + 1);
1841
+ for (let i = start; i <= end; i++) {
1842
+ pages.push(i);
1843
+ }
1844
+ if (current < total - 2) {
1845
+ pages.push("ellipsis");
1846
+ }
1847
+ if (total > 1) {
1848
+ pages.push(total);
1849
+ }
1850
+ return pages;
1851
+ }
1852
+ function TablePagination({
1853
+ currentPage,
1854
+ totalPages,
1855
+ onPageChange
1856
+ }) {
1857
+ const pages = getVisiblePages(currentPage, totalPages);
1858
+ const canGoBack = currentPage > 0;
1859
+ const canGoForward = currentPage < totalPages - 1;
1860
+ return /* @__PURE__ */ jsxs10(View13, { style: [styles12.container, { borderTopColor: "#e9e8e7" }], children: [
1861
+ /* @__PURE__ */ jsxs10(
1862
+ Pressable10,
1863
+ {
1864
+ disabled: !canGoBack,
1865
+ onPress: () => canGoBack && onPageChange(currentPage - 1),
1866
+ style: ({ pressed }) => [
1867
+ styles12.navButton,
1868
+ {
1869
+ opacity: !canGoBack ? 0.32 : 1,
1870
+ backgroundColor: "#faf9f7",
1871
+ borderColor: "#d9d8d7"
1872
+ },
1873
+ pressed && { opacity: 0.6 }
1874
+ ],
1875
+ children: [
1876
+ /* @__PURE__ */ jsx16(View13, { style: { transform: [{ rotate: "180deg" }] }, children: /* @__PURE__ */ jsx16(Icon, { name: "caret-right", size: 20, color: "#101828" }) }),
1877
+ /* @__PURE__ */ jsx16(Text, { variant: "body", textStyle: { color: "#101828", fontSize: 14, fontWeight: "600" }, children: "Anterior" })
1878
+ ]
1879
+ }
1880
+ ),
1881
+ /* @__PURE__ */ jsx16(View13, { style: styles12.pageNumbers, children: pages.map((page, index) => {
1882
+ if (page === "ellipsis") {
1883
+ return /* @__PURE__ */ jsx16(View13, { style: styles12.pageCell, children: /* @__PURE__ */ jsx16(Text, { variant: "body", textStyle: { color: "#737271", fontSize: 14, fontWeight: "500" }, children: "..." }) }, `ellipsis-${index}`);
1884
+ }
1885
+ const isActive = page - 1 === currentPage;
1886
+ return /* @__PURE__ */ jsx16(
1887
+ Pressable10,
1888
+ {
1889
+ onPress: () => onPageChange(page - 1),
1890
+ style: [
1891
+ styles12.pageCell,
1892
+ {
1893
+ backgroundColor: isActive ? "#e9e8e7" : "transparent",
1894
+ borderRadius: 8
1895
+ },
1896
+ isActive && {
1897
+ borderColor: "#cefe00",
1898
+ borderWidth: 1,
1899
+ ...elevation.xs
1900
+ }
1901
+ ],
1902
+ children: /* @__PURE__ */ jsx16(
1903
+ Text,
1904
+ {
1905
+ variant: "body",
1906
+ textStyle: {
1907
+ color: isActive ? "#141414" : "#737271",
1908
+ fontSize: 14,
1909
+ fontWeight: "500"
1910
+ },
1911
+ children: page
1912
+ }
1913
+ )
1914
+ },
1915
+ page
1916
+ );
1917
+ }) }),
1918
+ /* @__PURE__ */ jsxs10(
1919
+ Pressable10,
1920
+ {
1921
+ disabled: !canGoForward,
1922
+ onPress: () => canGoForward && onPageChange(currentPage + 1),
1923
+ style: ({ pressed }) => [
1924
+ styles12.navButton,
1925
+ {
1926
+ opacity: !canGoForward ? 0.32 : 1,
1927
+ backgroundColor: "#faf9f7",
1928
+ borderColor: "#d9d8d7"
1929
+ },
1930
+ pressed && { opacity: 0.6 }
1931
+ ],
1932
+ children: [
1933
+ /* @__PURE__ */ jsx16(Text, { variant: "body", textStyle: { color: "#101828", fontSize: 14, fontWeight: "600" }, children: "Pr\xF3ximo" }),
1934
+ /* @__PURE__ */ jsx16(Icon, { name: "caret-right", size: 20, color: "#101828" })
1935
+ ]
1936
+ }
1937
+ )
1938
+ ] });
1939
+ }
1940
+ var styles12 = StyleSheet12.create({
1941
+ container: {
1942
+ flexDirection: "row",
1943
+ alignItems: "center",
1944
+ justifyContent: "space-between",
1945
+ paddingVertical: 12,
1946
+ paddingHorizontal: 24,
1947
+ borderTopWidth: 1
1948
+ },
1949
+ navButton: {
1950
+ flexDirection: "row",
1951
+ alignItems: "center",
1952
+ gap: 8,
1953
+ height: 36,
1954
+ paddingHorizontal: 14,
1955
+ borderRadius: 16,
1956
+ borderWidth: 1
1957
+ },
1958
+ pageNumbers: {
1959
+ flexDirection: "row",
1960
+ alignItems: "center",
1961
+ gap: 2
1962
+ },
1963
+ pageCell: {
1964
+ width: 40,
1965
+ height: 40,
1966
+ alignItems: "center",
1967
+ justifyContent: "center"
1968
+ }
1969
+ });
1970
+
1971
+ // components/LinkButton.tsx
1972
+ import { Pressable as Pressable11, StyleSheet as StyleSheet13 } from "react-native";
1973
+ import { jsx as jsx17, jsxs as jsxs11 } from "react/jsx-runtime";
1974
+ function LinkButton({
1975
+ label,
1976
+ icon,
1977
+ color = "primary",
1978
+ disabled,
1979
+ ...rest
1980
+ }) {
1981
+ const textColor = color === "primary" ? "#cefe00" : "#737271";
1982
+ return /* @__PURE__ */ jsxs11(
1983
+ Pressable11,
1984
+ {
1985
+ accessibilityRole: "button",
1986
+ disabled,
1987
+ style: ({ pressed }) => [
1988
+ styles13.container,
1989
+ pressed && styles13.pressed,
1990
+ disabled && styles13.disabled
1991
+ ],
1992
+ ...rest,
1993
+ children: [
1994
+ icon && /* @__PURE__ */ jsx17(Icon, { name: icon, size: 16, color: textColor }),
1995
+ /* @__PURE__ */ jsx17(
1996
+ Text,
1997
+ {
1998
+ variant: "body",
1999
+ textStyle: [styles13.label, { color: textColor }],
2000
+ children: label
2001
+ }
2002
+ )
2003
+ ]
2004
+ }
2005
+ );
2006
+ }
2007
+ var styles13 = StyleSheet13.create({
2008
+ container: {
2009
+ flexDirection: "row",
2010
+ alignItems: "center",
2011
+ gap: spacing.xs,
2012
+ alignSelf: "flex-start",
2013
+ paddingVertical: spacing.xs
2014
+ },
2015
+ pressed: {
2016
+ opacity: 0.6
2017
+ },
2018
+ disabled: {
2019
+ opacity: 0.32
2020
+ },
2021
+ label: {
2022
+ fontSize: 14,
2023
+ lineHeight: 21,
2024
+ fontWeight: "500"
2025
+ }
2026
+ });
2027
+
2028
+ // components/BottomNavBar.tsx
2029
+ import { Pressable as Pressable12, StyleSheet as StyleSheet14, View as View14 } from "react-native";
2030
+ import { jsx as jsx18 } from "react/jsx-runtime";
2031
+ function BottomNavBar({ items, activeItemId, onItemPress }) {
2032
+ return /* @__PURE__ */ jsx18(
2033
+ View14,
2034
+ {
2035
+ style: [
2036
+ styles14.container,
2037
+ {
2038
+ backgroundColor: "#201f1fCC",
2039
+ borderColor: "#ffffff1A"
2040
+ }
2041
+ ],
2042
+ children: items.map((item) => {
2043
+ const isActive = item.id === activeItemId;
2044
+ return /* @__PURE__ */ jsx18(
2045
+ Pressable12,
2046
+ {
2047
+ accessibilityRole: "button",
2048
+ accessibilityState: { selected: isActive },
2049
+ onPress: () => onItemPress(item.id),
2050
+ style: ({ pressed }) => [
2051
+ styles14.item,
2052
+ pressed && styles14.pressed
2053
+ ],
2054
+ children: isActive ? /* @__PURE__ */ jsx18(View14, { style: styles14.activeItem, children: /* @__PURE__ */ jsx18(
2055
+ Icon,
2056
+ {
2057
+ name: item.icon,
2058
+ size: 25,
2059
+ color: "#141414",
2060
+ weight: "regular"
2061
+ }
2062
+ ) }) : /* @__PURE__ */ jsx18(View14, { style: styles14.inactiveItem, children: /* @__PURE__ */ jsx18(
2063
+ Icon,
2064
+ {
2065
+ name: item.icon,
2066
+ size: 25,
2067
+ color: "#8e8d8b",
2068
+ weight: "regular"
2069
+ }
2070
+ ) })
2071
+ },
2072
+ item.id
2073
+ );
2074
+ })
2075
+ }
2076
+ );
2077
+ }
2078
+ var styles14 = StyleSheet14.create({
2079
+ container: {
2080
+ flexDirection: "row",
2081
+ alignItems: "center",
2082
+ justifyContent: "space-between",
2083
+ padding: 12,
2084
+ borderRadius: 9999,
2085
+ borderWidth: 1
2086
+ },
2087
+ item: {
2088
+ alignItems: "center",
2089
+ justifyContent: "center"
2090
+ },
2091
+ pressed: {
2092
+ opacity: 0.6
2093
+ },
2094
+ activeItem: {
2095
+ width: 55,
2096
+ height: 55,
2097
+ borderRadius: 9999,
2098
+ backgroundColor: "#cefe00",
2099
+ alignItems: "center",
2100
+ justifyContent: "center",
2101
+ shadowColor: "#caf300",
2102
+ shadowOffset: { width: 0, height: 0 },
2103
+ shadowOpacity: 0.4,
2104
+ shadowRadius: 15,
2105
+ elevation: 8
2106
+ },
2107
+ inactiveItem: {
2108
+ width: 60,
2109
+ height: 60,
2110
+ borderRadius: 9999,
2111
+ alignItems: "center",
2112
+ justifyContent: "center",
2113
+ padding: 8
2114
+ }
2115
+ });
2116
+
2117
+ // components/ProgressBar.tsx
2118
+ import { useEffect, useRef } from "react";
2119
+ import { Animated, Easing, StyleSheet as StyleSheet15, View as View15 } from "react-native";
2120
+ import { jsx as jsx19, jsxs as jsxs12 } from "react/jsx-runtime";
2121
+ function ProgressBar({ value, showLabel = true, animated = true }) {
2122
+ const clampedValue = Math.max(0, Math.min(1, value));
2123
+ const animValue = useRef(new Animated.Value(animated ? 0 : clampedValue)).current;
2124
+ useEffect(() => {
2125
+ if (animated) {
2126
+ Animated.timing(animValue, {
2127
+ toValue: clampedValue,
2128
+ duration: 400,
2129
+ easing: Easing.out(Easing.cubic),
2130
+ useNativeDriver: false
2131
+ }).start();
2132
+ } else {
2133
+ animValue.setValue(clampedValue);
2134
+ }
2135
+ }, [clampedValue, animated, animValue]);
2136
+ const fillWidth = animValue.interpolate({
2137
+ inputRange: [0, 1],
2138
+ outputRange: ["0%", "100%"]
2139
+ });
2140
+ const percentage = Math.round(clampedValue * 100);
2141
+ return /* @__PURE__ */ jsx19(View15, { style: styles15.container, children: /* @__PURE__ */ jsxs12(View15, { style: styles15.barRow, children: [
2142
+ /* @__PURE__ */ jsx19(View15, { style: styles15.track, children: /* @__PURE__ */ jsx19(
2143
+ Animated.View,
2144
+ {
2145
+ style: [
2146
+ styles15.fill,
2147
+ { width: fillWidth }
2148
+ ]
2149
+ }
2150
+ ) }),
2151
+ showLabel && /* @__PURE__ */ jsxs12(
2152
+ Text,
2153
+ {
2154
+ variant: "body",
2155
+ textStyle: styles15.label,
2156
+ children: [
2157
+ percentage,
2158
+ "%"
2159
+ ]
2160
+ }
2161
+ )
2162
+ ] }) });
2163
+ }
2164
+ var styles15 = StyleSheet15.create({
2165
+ container: {
2166
+ width: "100%"
2167
+ },
2168
+ barRow: {
2169
+ flexDirection: "row",
2170
+ alignItems: "center",
2171
+ gap: 12
2172
+ },
2173
+ track: {
2174
+ flex: 1,
2175
+ height: 8,
2176
+ borderRadius: 4,
2177
+ backgroundColor: "#e9e8e7",
2178
+ overflow: "hidden"
2179
+ },
2180
+ fill: {
2181
+ height: 8,
2182
+ borderRadius: 4,
2183
+ backgroundColor: "#63ca7e"
2184
+ },
2185
+ label: {
2186
+ fontSize: 14,
2187
+ lineHeight: 21,
2188
+ fontWeight: "500",
2189
+ color: "#737271",
2190
+ minWidth: 34
2191
+ }
2192
+ });
2193
+
2194
+ // components/SearchBar.tsx
2195
+ import { useState as useState6 } from "react";
2196
+ import {
2197
+ Pressable as Pressable13,
2198
+ StyleSheet as StyleSheet16,
2199
+ TextInput as TextInput3,
2200
+ View as View16
2201
+ } from "react-native";
2202
+ import { jsx as jsx20, jsxs as jsxs13 } from "react/jsx-runtime";
2203
+ function SearchBar({
2204
+ label,
2205
+ value,
2206
+ onChangeText,
2207
+ placeholder = "Search",
2208
+ disabled = false,
2209
+ onClear,
2210
+ ...rest
2211
+ }) {
2212
+ const [isFocused, setIsFocused] = useState6(false);
2213
+ const [isHovered, setIsHovered] = useState6(false);
2214
+ const hasValue = !!value && value.length > 0;
2215
+ const getBorderColor = () => {
2216
+ if (isFocused) {
2217
+ return "#cefe00";
2218
+ }
2219
+ return "#d9d8d7";
2220
+ };
2221
+ const getBoxShadow = () => {
2222
+ if (isFocused) {
2223
+ return {
2224
+ shadowColor: "#fff6d4",
2225
+ shadowOffset: { width: 0, height: 0 },
2226
+ shadowOpacity: 1,
2227
+ shadowRadius: 0,
2228
+ elevation: 0
2229
+ };
2230
+ }
2231
+ return elevation.xs;
2232
+ };
2233
+ return /* @__PURE__ */ jsxs13(View16, { style: [styles16.wrapper, disabled && styles16.disabledWrapper], children: [
2234
+ label && /* @__PURE__ */ jsx20(Text, { variant: "body", textStyle: [styles16.label, { color: "#737271" }], children: label }),
2235
+ /* @__PURE__ */ jsxs13(
2236
+ Pressable13,
2237
+ {
2238
+ disabled,
2239
+ onHoverIn: () => setIsHovered(true),
2240
+ onHoverOut: () => setIsHovered(false),
2241
+ style: [
2242
+ styles16.container,
2243
+ {
2244
+ backgroundColor: isHovered && !isFocused ? "#e9e8e7" : "#faf9f7",
2245
+ borderColor: getBorderColor(),
2246
+ borderWidth: 1,
2247
+ borderRadius: 8
2248
+ },
2249
+ getBoxShadow()
2250
+ ],
2251
+ children: [
2252
+ /* @__PURE__ */ jsx20(Icon, { name: "magnifying-glass", size: 20, color: "#667085" }),
2253
+ /* @__PURE__ */ jsx20(
2254
+ TextInput3,
2255
+ {
2256
+ style: [styles16.input, { color: hasValue ? "#141414" : "#8e8d8b" }],
2257
+ value,
2258
+ onChangeText,
2259
+ placeholder,
2260
+ placeholderTextColor: "#8e8d8b",
2261
+ editable: !disabled,
2262
+ onFocus: () => setIsFocused(true),
2263
+ onBlur: () => setIsFocused(false),
2264
+ ...rest
2265
+ }
2266
+ ),
2267
+ hasValue && !disabled && /* @__PURE__ */ jsx20(
2268
+ Pressable13,
2269
+ {
2270
+ onPress: () => {
2271
+ onChangeText?.("");
2272
+ onClear?.();
2273
+ },
2274
+ hitSlop: 8,
2275
+ style: styles16.clearButton,
2276
+ children: /* @__PURE__ */ jsx20(Icon, { name: "x-circle", size: 16, color: "#737271" })
2277
+ }
2278
+ )
2279
+ ]
2280
+ }
2281
+ )
2282
+ ] });
2283
+ }
2284
+ var styles16 = StyleSheet16.create({
2285
+ wrapper: {
2286
+ gap: 4
2287
+ },
2288
+ disabledWrapper: {
2289
+ opacity: 0.32
2290
+ },
2291
+ label: {
2292
+ fontSize: 14,
2293
+ lineHeight: 21,
2294
+ fontWeight: "500"
2295
+ },
2296
+ container: {
2297
+ flexDirection: "row",
2298
+ alignItems: "center",
2299
+ height: 44,
2300
+ paddingHorizontal: 14,
2301
+ gap: 8
2302
+ },
2303
+ input: {
2304
+ flex: 1,
2305
+ paddingVertical: 0,
2306
+ includeFontPadding: false,
2307
+ fontSize: 14,
2308
+ lineHeight: 21
2309
+ },
2310
+ clearButton: {
2311
+ padding: 2
2312
+ }
2313
+ });
2314
+
2315
+ // components/Slider.tsx
2316
+ import { useCallback, useRef as useRef2 } from "react";
2317
+ import { PanResponder, StyleSheet as StyleSheet17, View as View17 } from "react-native";
2318
+ import { jsx as jsx21, jsxs as jsxs14 } from "react/jsx-runtime";
2319
+ function Slider({
2320
+ value,
2321
+ minimumValue = 0,
2322
+ maximumValue = 100,
2323
+ step = 1,
2324
+ onValueChange,
2325
+ disabled = false,
2326
+ showValueLabel = true
2327
+ }) {
2328
+ const trackWidthRef = useRef2(0);
2329
+ const range = maximumValue - minimumValue;
2330
+ const percentage = range > 0 ? (value - minimumValue) / range : 0;
2331
+ const clampToStep = useCallback(
2332
+ (raw) => {
2333
+ const stepped = Math.round((raw - minimumValue) / step) * step + minimumValue;
2334
+ return Math.max(minimumValue, Math.min(maximumValue, stepped));
2335
+ },
2336
+ [minimumValue, maximumValue, step]
2337
+ );
2338
+ const panResponder = useRef2(
2339
+ PanResponder.create({
2340
+ onStartShouldSetPanResponder: () => !disabled,
2341
+ onMoveShouldSetPanResponder: () => !disabled,
2342
+ onPanResponderMove: (_, gestureState) => {
2343
+ if (trackWidthRef.current === 0) {
2344
+ return;
2345
+ }
2346
+ const newX = Math.max(
2347
+ 0,
2348
+ Math.min(1, (gestureState.x0 + gestureState.dx) / trackWidthRef.current)
2349
+ );
2350
+ const rawValue = newX * range + minimumValue;
2351
+ onValueChange(clampToStep(rawValue));
2352
+ }
2353
+ })
2354
+ ).current;
2355
+ const onTrackLayout = useCallback((e) => {
2356
+ trackWidthRef.current = e.nativeEvent.layout.width;
2357
+ }, []);
2358
+ return /* @__PURE__ */ jsxs14(View17, { style: [styles17.wrapper, disabled && styles17.disabled], children: [
2359
+ showValueLabel && /* @__PURE__ */ jsxs14(
2360
+ Text,
2361
+ {
2362
+ variant: "body",
2363
+ textStyle: [styles17.valueLabel, { color: "#101828" }],
2364
+ children: [
2365
+ String(value),
2366
+ "%"
2367
+ ]
2368
+ }
2369
+ ),
2370
+ /* @__PURE__ */ jsxs14(
2371
+ View17,
2372
+ {
2373
+ onLayout: onTrackLayout,
2374
+ ...panResponder.panHandlers,
2375
+ style: styles17.trackContainer,
2376
+ children: [
2377
+ /* @__PURE__ */ jsx21(View17, { style: styles17.track, children: /* @__PURE__ */ jsx21(
2378
+ View17,
2379
+ {
2380
+ style: [
2381
+ styles17.fill,
2382
+ { width: `${percentage * 100}%` }
2383
+ ]
2384
+ }
2385
+ ) }),
2386
+ /* @__PURE__ */ jsx21(
2387
+ View17,
2388
+ {
2389
+ style: [
2390
+ styles17.thumb,
2391
+ {
2392
+ left: `${percentage * 100}%`
2393
+ }
2394
+ ],
2395
+ children: /* @__PURE__ */ jsx21(View17, { style: styles17.thumbInner })
2396
+ }
2397
+ )
2398
+ ]
2399
+ }
2400
+ )
2401
+ ] });
2402
+ }
2403
+ var styles17 = StyleSheet17.create({
2404
+ wrapper: {
2405
+ gap: spacing.sm
2406
+ },
2407
+ disabled: {
2408
+ opacity: 0.32
2409
+ },
2410
+ valueLabel: {
2411
+ fontSize: 16,
2412
+ lineHeight: 24,
2413
+ fontWeight: "500",
2414
+ textAlign: "center"
2415
+ },
2416
+ trackContainer: {
2417
+ position: "relative",
2418
+ height: 40,
2419
+ justifyContent: "center"
2420
+ },
2421
+ track: {
2422
+ height: 8,
2423
+ borderRadius: 4,
2424
+ backgroundColor: "#e9e8e7",
2425
+ overflow: "hidden"
2426
+ },
2427
+ fill: {
2428
+ height: 8,
2429
+ borderRadius: 4,
2430
+ backgroundColor: "#cefe00"
2431
+ },
2432
+ thumb: {
2433
+ position: "absolute",
2434
+ width: 24,
2435
+ height: 24,
2436
+ marginLeft: -12,
2437
+ top: 8,
2438
+ alignItems: "center",
2439
+ justifyContent: "center"
2440
+ },
2441
+ thumbInner: {
2442
+ width: 24,
2443
+ height: 24,
2444
+ borderRadius: 12,
2445
+ backgroundColor: "#ffffff",
2446
+ borderWidth: 1.5,
2447
+ borderColor: "#cefe00",
2448
+ shadowColor: "#101828",
2449
+ shadowOffset: { width: 0, height: 2 },
2450
+ shadowOpacity: 0.16,
2451
+ shadowRadius: 6,
2452
+ elevation: 4
2453
+ }
2454
+ });
2455
+
2456
+ // components/TabMenu.tsx
2457
+ import { useState as useState7 } from "react";
2458
+ import { Pressable as Pressable14, StyleSheet as StyleSheet18, View as View18 } from "react-native";
2459
+ import { jsx as jsx22 } from "react/jsx-runtime";
2460
+ function TabMenu({ tabs, activeTabId, onTabChange }) {
2461
+ const [hoveredId, setHoveredId] = useState7(null);
2462
+ return /* @__PURE__ */ jsx22(View18, { style: styles18.container, children: tabs.map((tab) => {
2463
+ const isActive = tab.id === activeTabId;
2464
+ const isHovered = tab.id === hoveredId;
2465
+ return /* @__PURE__ */ jsx22(
2466
+ Pressable14,
2467
+ {
2468
+ accessibilityRole: "tab",
2469
+ accessibilityState: { selected: isActive },
2470
+ onPress: () => onTabChange(tab.id),
2471
+ onHoverIn: () => setHoveredId(tab.id),
2472
+ onHoverOut: () => setHoveredId(null),
2473
+ style: [
2474
+ styles18.tab,
2475
+ {
2476
+ borderBottomColor: isActive ? "#cefe00" : "#e9e8e7",
2477
+ borderBottomWidth: isActive ? 2 : 1,
2478
+ backgroundColor: isHovered && !isActive ? "#e9e8e7" : "transparent"
2479
+ }
2480
+ ],
2481
+ children: /* @__PURE__ */ jsx22(
2482
+ Text,
2483
+ {
2484
+ variant: "body",
2485
+ textStyle: [
2486
+ styles18.label,
2487
+ {
2488
+ color: isActive ? "#cefe00" : "#737271",
2489
+ fontWeight: isActive ? "700" : "400"
2490
+ }
2491
+ ],
2492
+ children: tab.label
2493
+ }
2494
+ )
2495
+ },
2496
+ tab.id
2497
+ );
2498
+ }) });
2499
+ }
2500
+ var styles18 = StyleSheet18.create({
2501
+ container: {
2502
+ flexDirection: "row"
2503
+ },
2504
+ tab: {
2505
+ flex: 1,
2506
+ alignItems: "center",
2507
+ justifyContent: "center",
2508
+ paddingVertical: 4,
2509
+ paddingBottom: 12
2510
+ },
2511
+ label: {
2512
+ fontSize: 16,
2513
+ lineHeight: 24
2514
+ }
2515
+ });
2516
+ export {
2517
+ Autocomplete,
2518
+ Badge,
2519
+ BottomNavBar,
2520
+ Box,
2521
+ Button,
2522
+ Card,
2523
+ Checkbox,
2524
+ DatePicker,
2525
+ DropdownSelect,
2526
+ Icon,
2527
+ InputField,
2528
+ LinkButton,
2529
+ ProgressBar,
2530
+ SearchBar,
2531
+ SegmentedTabs,
2532
+ Slider,
2533
+ TabMenu,
2534
+ TablePagination,
2535
+ Tag,
2536
+ Text,
2537
+ ThemeProvider,
2538
+ Toggle,
2539
+ colorMap,
2540
+ darkColors,
2541
+ elevation,
2542
+ lightColors,
2543
+ radius,
2544
+ radiusMap,
2545
+ spacing,
2546
+ spacingMap,
2547
+ typography,
2548
+ useTheme
2549
+ };