@retray-dev/ui-kit 0.1.0 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/COMPONENTS.md +710 -0
  2. package/LICENSE +21 -0
  3. package/README.md +150 -0
  4. package/dist/index.d.mts +345 -4
  5. package/dist/index.d.ts +345 -4
  6. package/dist/index.js +1644 -58
  7. package/dist/index.mjs +1590 -58
  8. package/package.json +44 -5
  9. package/src/components/Accordion/Accordion.tsx +173 -0
  10. package/src/components/Accordion/index.ts +2 -0
  11. package/src/components/Alert/Alert.tsx +59 -0
  12. package/src/components/Alert/index.ts +2 -0
  13. package/src/components/Avatar/Avatar.tsx +71 -0
  14. package/src/components/Avatar/index.ts +2 -0
  15. package/src/components/Badge/Badge.tsx +48 -0
  16. package/src/components/Badge/index.ts +2 -0
  17. package/src/components/Button/Button.tsx +94 -45
  18. package/src/components/Card/Card.tsx +103 -0
  19. package/src/components/Card/index.ts +9 -0
  20. package/src/components/Checkbox/Checkbox.tsx +98 -0
  21. package/src/components/Checkbox/index.ts +2 -0
  22. package/src/components/EmptyState/EmptyState.tsx +67 -0
  23. package/src/components/EmptyState/index.ts +2 -0
  24. package/src/components/Input/Input.tsx +28 -35
  25. package/src/components/Progress/Progress.tsx +52 -0
  26. package/src/components/Progress/index.ts +2 -0
  27. package/src/components/RadioGroup/RadioGroup.tsx +132 -0
  28. package/src/components/RadioGroup/index.ts +2 -0
  29. package/src/components/Select/Select.tsx +232 -0
  30. package/src/components/Select/index.ts +2 -0
  31. package/src/components/Separator/Separator.tsx +33 -0
  32. package/src/components/Separator/index.ts +2 -0
  33. package/src/components/Sheet/Sheet.tsx +115 -0
  34. package/src/components/Sheet/index.ts +2 -0
  35. package/src/components/Skeleton/Skeleton.tsx +63 -0
  36. package/src/components/Skeleton/index.ts +2 -0
  37. package/src/components/Slider/Slider.tsx +143 -0
  38. package/src/components/Slider/index.ts +2 -0
  39. package/src/components/Spinner/Spinner.tsx +21 -0
  40. package/src/components/Spinner/index.ts +2 -0
  41. package/src/components/Switch/Switch.tsx +86 -0
  42. package/src/components/Switch/index.ts +2 -0
  43. package/src/components/Tabs/Tabs.tsx +196 -0
  44. package/src/components/Tabs/index.ts +2 -0
  45. package/src/components/Text/Text.tsx +10 -4
  46. package/src/components/Textarea/Textarea.tsx +89 -0
  47. package/src/components/Textarea/index.ts +2 -0
  48. package/src/components/Toast/Toast.tsx +200 -0
  49. package/src/components/Toast/index.ts +2 -0
  50. package/src/components/Toggle/Toggle.tsx +92 -0
  51. package/src/components/Toggle/index.ts +2 -0
  52. package/src/index.ts +26 -0
  53. package/src/theme/ThemeProvider.tsx +47 -0
  54. package/src/theme/colors.ts +45 -0
  55. package/src/theme/index.ts +4 -0
  56. package/src/theme/types.ts +33 -0
package/dist/index.mjs CHANGED
@@ -1,28 +1,86 @@
1
- import React3, { useState } from 'react';
2
- import { StyleSheet, TouchableOpacity, ActivityIndicator, Text, View, TextInput } from 'react-native';
1
+ import React23, { createContext, useMemo, useContext, useRef, useState, useEffect, useCallback } from 'react';
2
+ import { StyleSheet, useColorScheme, Animated, TouchableOpacity, ActivityIndicator, Text, View, TextInput, Image, PanResponder } from 'react-native';
3
+ import * as Haptics11 from 'expo-haptics';
4
+ import { LinearGradient } from 'expo-linear-gradient';
5
+ import ReanimatedAnimated, { useSharedValue, useAnimatedStyle, withTiming, Easing, runOnJS, withSpring } from 'react-native-reanimated';
6
+ import { BottomSheetModal, BottomSheetView, BottomSheetBackdrop } from '@gorhom/bottom-sheet';
7
+ export { BottomSheetModalProvider } from '@gorhom/bottom-sheet';
8
+ import { Gesture, GestureDetector } from 'react-native-gesture-handler';
9
+ import { useSafeAreaInsets } from 'react-native-safe-area-context';
3
10
 
4
- // src/components/Button/Button.tsx
5
- var containerVariantStyles = {
6
- primary: { backgroundColor: "#000" },
7
- secondary: { backgroundColor: "#6B7280" },
8
- outline: { backgroundColor: "transparent", borderWidth: 1.5, borderColor: "#000" },
9
- ghost: { backgroundColor: "transparent" }
11
+ // src/theme/ThemeProvider.tsx
12
+
13
+ // src/theme/colors.ts
14
+ var defaultLight = {
15
+ background: "#ffffff",
16
+ foreground: "#171717",
17
+ card: "#ffffff",
18
+ cardForeground: "#171717",
19
+ primary: "#1a1a1a",
20
+ primaryForeground: "#fafafa",
21
+ secondary: "#f5f5f5",
22
+ secondaryForeground: "#1a1a1a",
23
+ muted: "#f5f5f5",
24
+ mutedForeground: "#646464",
25
+ accent: "#f5f5f5",
26
+ accentForeground: "#1a1a1a",
27
+ destructive: "#ef4444",
28
+ destructiveForeground: "#fafafa",
29
+ border: "#e5e5e5",
30
+ input: "#e5e5e5",
31
+ ring: "#a3a3a3",
32
+ success: "#16a34a",
33
+ successForeground: "#ffffff"
10
34
  };
11
- var containerSizeStyles = {
12
- sm: { paddingHorizontal: 12, paddingVertical: 6 },
13
- md: { paddingHorizontal: 16, paddingVertical: 10 },
14
- lg: { paddingHorizontal: 24, paddingVertical: 14 }
35
+ var defaultDark = {
36
+ background: "#171717",
37
+ foreground: "#fafafa",
38
+ card: "#1f1f1f",
39
+ cardForeground: "#fafafa",
40
+ primary: "#fafafa",
41
+ primaryForeground: "#1a1a1a",
42
+ secondary: "#2a2a2a",
43
+ secondaryForeground: "#fafafa",
44
+ muted: "#2a2a2a",
45
+ mutedForeground: "#a3a3a3",
46
+ accent: "#2a2a2a",
47
+ accentForeground: "#fafafa",
48
+ destructive: "#dc2626",
49
+ destructiveForeground: "#fafafa",
50
+ border: "#2a2a2a",
51
+ input: "#2a2a2a",
52
+ ring: "#d4d4d4",
53
+ success: "#22c55e",
54
+ successForeground: "#ffffff"
15
55
  };
16
- var labelVariantStyles = {
17
- primary: { color: "#fff" },
18
- secondary: { color: "#fff" },
19
- outline: { color: "#000" },
20
- ghost: { color: "#000" }
56
+
57
+ // src/theme/ThemeProvider.tsx
58
+ var ThemeContext = createContext({
59
+ colors: defaultLight,
60
+ colorScheme: "light"
61
+ });
62
+ function ThemeProvider({ children, theme, colorScheme = "system" }) {
63
+ const systemScheme = useColorScheme() ?? "light";
64
+ const resolvedScheme = colorScheme === "system" ? systemScheme : colorScheme;
65
+ const colors = useMemo(() => {
66
+ const base = resolvedScheme === "dark" ? defaultDark : defaultLight;
67
+ const overrides = resolvedScheme === "dark" ? theme?.dark : theme?.light;
68
+ return { ...base, ...overrides };
69
+ }, [resolvedScheme, theme]);
70
+ return /* @__PURE__ */ React23.createElement(ThemeContext.Provider, { value: { colors, colorScheme: resolvedScheme } }, children);
71
+ }
72
+ function useTheme() {
73
+ return useContext(ThemeContext);
74
+ }
75
+ var containerSizeStyles = {
76
+ sm: { paddingHorizontal: 16, paddingVertical: 10 },
77
+ md: { paddingHorizontal: 20, paddingVertical: 14 },
78
+ lg: { paddingHorizontal: 28, paddingVertical: 18 }
21
79
  };
22
80
  var labelSizeStyles = {
23
- sm: { fontSize: 13 },
24
- md: { fontSize: 15 },
25
- lg: { fontSize: 17 }
81
+ sm: { fontSize: 14 },
82
+ md: { fontSize: 16 },
83
+ lg: { fontSize: 18 }
26
84
  };
27
85
  function Button({
28
86
  label,
@@ -30,34 +88,66 @@ function Button({
30
88
  size = "md",
31
89
  loading = false,
32
90
  fullWidth = false,
91
+ icon,
92
+ iconPosition = "left",
33
93
  disabled,
34
94
  style,
95
+ onPress,
35
96
  ...props
36
97
  }) {
98
+ const { colors } = useTheme();
37
99
  const isDisabled = disabled || loading;
38
- return /* @__PURE__ */ React3.createElement(
100
+ const scale = useRef(new Animated.Value(1)).current;
101
+ const handlePressIn = () => {
102
+ if (isDisabled) return;
103
+ Animated.spring(scale, {
104
+ toValue: 0.95,
105
+ useNativeDriver: true,
106
+ speed: 40,
107
+ bounciness: 0
108
+ }).start();
109
+ };
110
+ const handlePressOut = () => {
111
+ Animated.spring(scale, { toValue: 1, useNativeDriver: true, speed: 40, bounciness: 4 }).start();
112
+ };
113
+ const handlePress = (e) => {
114
+ Haptics11.impactAsync(Haptics11.ImpactFeedbackStyle.Light);
115
+ onPress?.(e);
116
+ };
117
+ const containerVariantStyle = {
118
+ primary: { backgroundColor: colors.primary },
119
+ secondary: { backgroundColor: colors.secondary },
120
+ outline: { backgroundColor: "transparent", borderWidth: 1.5, borderColor: colors.border },
121
+ ghost: { backgroundColor: "transparent" }
122
+ }[variant];
123
+ const labelVariantStyle = {
124
+ primary: { color: colors.primaryForeground },
125
+ secondary: { color: colors.secondaryForeground },
126
+ outline: { color: colors.foreground },
127
+ ghost: { color: colors.foreground }
128
+ }[variant];
129
+ const spinnerColor = variant === "primary" || variant === "secondary" ? colors.primaryForeground : colors.foreground;
130
+ return /* @__PURE__ */ React23.createElement(Animated.View, { style: [fullWidth && styles.fullWidth, { transform: [{ scale }] }] }, /* @__PURE__ */ React23.createElement(
39
131
  TouchableOpacity,
40
132
  {
41
133
  style: [
42
134
  styles.base,
43
- containerVariantStyles[variant],
135
+ containerVariantStyle,
44
136
  containerSizeStyles[size],
45
137
  fullWidth && styles.fullWidth,
46
138
  isDisabled && styles.disabled,
47
139
  style
48
140
  ],
49
141
  disabled: isDisabled,
50
- activeOpacity: 0.75,
142
+ activeOpacity: 1,
143
+ touchSoundDisabled: true,
144
+ onPress: handlePress,
145
+ onPressIn: handlePressIn,
146
+ onPressOut: handlePressOut,
51
147
  ...props
52
148
  },
53
- loading ? /* @__PURE__ */ React3.createElement(
54
- ActivityIndicator,
55
- {
56
- size: "small",
57
- color: variant === "outline" || variant === "ghost" ? "#000" : "#fff"
58
- }
59
- ) : /* @__PURE__ */ React3.createElement(Text, { style: [styles.label, labelVariantStyles[variant], labelSizeStyles[size]] }, label)
60
- );
149
+ loading ? /* @__PURE__ */ React23.createElement(ActivityIndicator, { size: "small", color: spinnerColor }) : /* @__PURE__ */ React23.createElement(React23.Fragment, null, icon && iconPosition === "left" && /* @__PURE__ */ React23.createElement(React23.Fragment, null, icon), /* @__PURE__ */ React23.createElement(Text, { style: [styles.label, labelVariantStyle, labelSizeStyles[size], icon ? styles.labelWithIcon : void 0] }, label), icon && iconPosition === "right" && /* @__PURE__ */ React23.createElement(React23.Fragment, null, icon))
150
+ ));
61
151
  }
62
152
  var styles = StyleSheet.create({
63
153
  base: {
@@ -74,35 +164,45 @@ var styles = StyleSheet.create({
74
164
  },
75
165
  label: {
76
166
  fontWeight: "600"
167
+ },
168
+ labelWithIcon: {
169
+ marginHorizontal: 6
77
170
  }
78
171
  });
79
172
  var variantStyles = {
80
- h1: { fontSize: 32, fontWeight: "700", lineHeight: 40 },
173
+ h1: { fontSize: 32, fontWeight: "700", lineHeight: 44 },
81
174
  h2: { fontSize: 24, fontWeight: "700", lineHeight: 32 },
82
175
  h3: { fontSize: 20, fontWeight: "600", lineHeight: 28 },
83
176
  body: { fontSize: 16, fontWeight: "400", lineHeight: 24 },
84
- caption: { fontSize: 12, fontWeight: "400", lineHeight: 18, color: "#6B7280" },
177
+ caption: { fontSize: 12, fontWeight: "400", lineHeight: 18 },
85
178
  label: { fontSize: 14, fontWeight: "500", lineHeight: 20 }
86
179
  };
87
180
  function Text2({ variant = "body", color, style, children, ...props }) {
88
- return /* @__PURE__ */ React3.createElement(
181
+ const { colors } = useTheme();
182
+ const defaultColor = variant === "caption" ? colors.mutedForeground : colors.foreground;
183
+ return /* @__PURE__ */ React23.createElement(
89
184
  Text,
90
185
  {
91
- style: [variantStyles[variant], color ? { color } : void 0, style],
186
+ style: [variantStyles[variant], { color: color ?? defaultColor }, style],
187
+ allowFontScaling: true,
92
188
  ...props
93
189
  },
94
190
  children
95
191
  );
96
192
  }
97
- function Input({ label, error, hint, style, onFocus, onBlur, ...props }) {
193
+ function Input({ label, error, hint, containerStyle, style, onFocus, onBlur, ...props }) {
194
+ const { colors } = useTheme();
98
195
  const [focused, setFocused] = useState(false);
99
- return /* @__PURE__ */ React3.createElement(View, { style: styles2.container }, label ? /* @__PURE__ */ React3.createElement(Text, { style: styles2.label }, label) : null, /* @__PURE__ */ React3.createElement(
196
+ return /* @__PURE__ */ React23.createElement(View, { style: [styles2.container, containerStyle] }, label ? /* @__PURE__ */ React23.createElement(Text, { style: [styles2.label, { color: colors.foreground }], allowFontScaling: true }, label) : null, /* @__PURE__ */ React23.createElement(
100
197
  TextInput,
101
198
  {
102
199
  style: [
103
200
  styles2.input,
104
- focused && styles2.inputFocused,
105
- error ? styles2.inputError : void 0,
201
+ {
202
+ borderColor: error ? colors.destructive : focused ? colors.ring : colors.border,
203
+ color: colors.foreground,
204
+ backgroundColor: colors.background
205
+ },
106
206
  style
107
207
  ],
108
208
  onFocus: (e) => {
@@ -113,10 +213,11 @@ function Input({ label, error, hint, style, onFocus, onBlur, ...props }) {
113
213
  setFocused(false);
114
214
  onBlur?.(e);
115
215
  },
116
- placeholderTextColor: "#9CA3AF",
216
+ placeholderTextColor: colors.mutedForeground,
217
+ allowFontScaling: true,
117
218
  ...props
118
219
  }
119
- ), error ? /* @__PURE__ */ React3.createElement(Text, { style: styles2.errorText }, error) : null, !error && hint ? /* @__PURE__ */ React3.createElement(Text, { style: styles2.hintText }, hint) : null);
220
+ ), error ? /* @__PURE__ */ React23.createElement(Text, { style: [styles2.helperText, { color: colors.destructive }], allowFontScaling: true }, error) : null, !error && hint ? /* @__PURE__ */ React23.createElement(Text, { style: [styles2.helperText, { color: colors.mutedForeground }], allowFontScaling: true }, hint) : null);
120
221
  }
121
222
  var styles2 = StyleSheet.create({
122
223
  container: {
@@ -125,33 +226,1464 @@ var styles2 = StyleSheet.create({
125
226
  label: {
126
227
  fontSize: 14,
127
228
  fontWeight: "500",
128
- color: "#111827",
129
- marginBottom: 2
229
+ marginBottom: 4
230
+ },
231
+ input: {
232
+ borderWidth: 1.5,
233
+ borderRadius: 8,
234
+ paddingHorizontal: 16,
235
+ paddingVertical: 14,
236
+ fontSize: 16
237
+ },
238
+ helperText: {
239
+ fontSize: 12
240
+ }
241
+ });
242
+ function Badge({ label, variant = "default", style }) {
243
+ const { colors } = useTheme();
244
+ const containerStyle = {
245
+ default: { backgroundColor: colors.primary },
246
+ secondary: { backgroundColor: colors.secondary },
247
+ destructive: { backgroundColor: colors.destructive },
248
+ outline: { backgroundColor: "transparent", borderWidth: 1, borderColor: colors.border }
249
+ }[variant];
250
+ const textColor = {
251
+ default: colors.primaryForeground,
252
+ secondary: colors.secondaryForeground,
253
+ destructive: colors.destructiveForeground,
254
+ outline: colors.foreground
255
+ }[variant];
256
+ return /* @__PURE__ */ React23.createElement(View, { style: [styles3.container, containerStyle, style] }, /* @__PURE__ */ React23.createElement(Text, { style: [styles3.label, { color: textColor }], allowFontScaling: true }, label));
257
+ }
258
+ var styles3 = StyleSheet.create({
259
+ container: {
260
+ borderRadius: 6,
261
+ paddingHorizontal: 8,
262
+ paddingVertical: 2,
263
+ alignSelf: "flex-start"
264
+ },
265
+ label: {
266
+ fontSize: 12,
267
+ fontWeight: "500"
268
+ }
269
+ });
270
+ function Card({ children, style }) {
271
+ const { colors } = useTheme();
272
+ return /* @__PURE__ */ React23.createElement(
273
+ View,
274
+ {
275
+ style: [styles4.card, { backgroundColor: colors.card, borderColor: colors.border }, style]
276
+ },
277
+ children
278
+ );
279
+ }
280
+ function CardHeader({ children, style }) {
281
+ return /* @__PURE__ */ React23.createElement(View, { style: [styles4.header, style] }, children);
282
+ }
283
+ function CardTitle({ children, style }) {
284
+ const { colors } = useTheme();
285
+ return /* @__PURE__ */ React23.createElement(Text, { style: [styles4.title, { color: colors.cardForeground }, style] }, children);
286
+ }
287
+ function CardDescription({ children, style }) {
288
+ const { colors } = useTheme();
289
+ return /* @__PURE__ */ React23.createElement(Text, { style: [styles4.description, { color: colors.mutedForeground }, style] }, children);
290
+ }
291
+ function CardContent({ children, style }) {
292
+ return /* @__PURE__ */ React23.createElement(View, { style: [styles4.content, style] }, children);
293
+ }
294
+ function CardFooter({ children, style }) {
295
+ return /* @__PURE__ */ React23.createElement(View, { style: [styles4.footer, style] }, children);
296
+ }
297
+ var styles4 = StyleSheet.create({
298
+ card: {
299
+ borderRadius: 12,
300
+ borderWidth: 1,
301
+ shadowColor: "#000",
302
+ shadowOffset: { width: 0, height: 1 },
303
+ shadowOpacity: 0.05,
304
+ shadowRadius: 2,
305
+ elevation: 1
306
+ },
307
+ header: {
308
+ padding: 24,
309
+ paddingBottom: 0,
310
+ gap: 6
311
+ },
312
+ title: {
313
+ fontSize: 18,
314
+ fontWeight: "600",
315
+ lineHeight: 24
316
+ },
317
+ description: {
318
+ fontSize: 14,
319
+ lineHeight: 20
320
+ },
321
+ content: {
322
+ padding: 24
323
+ },
324
+ footer: {
325
+ padding: 24,
326
+ paddingTop: 0,
327
+ flexDirection: "row",
328
+ alignItems: "center"
329
+ }
330
+ });
331
+ function Separator({ orientation = "horizontal", style }) {
332
+ const { colors } = useTheme();
333
+ return /* @__PURE__ */ React23.createElement(
334
+ View,
335
+ {
336
+ style: [
337
+ orientation === "horizontal" ? styles5.horizontal : styles5.vertical,
338
+ { backgroundColor: colors.border },
339
+ style
340
+ ]
341
+ }
342
+ );
343
+ }
344
+ var styles5 = StyleSheet.create({
345
+ horizontal: {
346
+ height: 1,
347
+ width: "100%"
348
+ },
349
+ vertical: {
350
+ width: 1,
351
+ height: "100%"
352
+ }
353
+ });
354
+ var sizeMap = {
355
+ sm: "small",
356
+ md: "small",
357
+ lg: "large"
358
+ };
359
+ function Spinner({ size = "md", color, ...props }) {
360
+ const { colors } = useTheme();
361
+ return /* @__PURE__ */ React23.createElement(ActivityIndicator, { size: sizeMap[size], color: color ?? colors.primary, ...props });
362
+ }
363
+ function Skeleton({ width = "100%", height = 16, borderRadius = 6, style }) {
364
+ const { colors, colorScheme } = useTheme();
365
+ const shimmerAnim = useRef(new Animated.Value(0)).current;
366
+ const [containerWidth, setContainerWidth] = useState(300);
367
+ const shimmerHighlight = colorScheme === "dark" ? "rgba(255,255,255,0.08)" : "rgba(255,255,255,0.7)";
368
+ useEffect(() => {
369
+ const animation = Animated.loop(
370
+ Animated.timing(shimmerAnim, {
371
+ toValue: 1,
372
+ duration: 1200,
373
+ useNativeDriver: true
374
+ })
375
+ );
376
+ animation.start();
377
+ return () => animation.stop();
378
+ }, [shimmerAnim]);
379
+ const translateX = shimmerAnim.interpolate({
380
+ inputRange: [0, 1],
381
+ outputRange: [-containerWidth, containerWidth]
382
+ });
383
+ return /* @__PURE__ */ React23.createElement(
384
+ View,
385
+ {
386
+ style: [
387
+ styles6.base,
388
+ { width, height, borderRadius, backgroundColor: colors.muted },
389
+ style
390
+ ],
391
+ onLayout: (e) => setContainerWidth(e.nativeEvent.layout.width)
392
+ },
393
+ /* @__PURE__ */ React23.createElement(Animated.View, { style: [StyleSheet.absoluteFill, { transform: [{ translateX }] }] }, /* @__PURE__ */ React23.createElement(
394
+ LinearGradient,
395
+ {
396
+ colors: ["transparent", shimmerHighlight, "transparent"],
397
+ start: { x: 0, y: 0 },
398
+ end: { x: 1, y: 0 },
399
+ style: StyleSheet.absoluteFill
400
+ }
401
+ ))
402
+ );
403
+ }
404
+ var styles6 = StyleSheet.create({
405
+ base: {
406
+ overflow: "hidden"
407
+ }
408
+ });
409
+ var sizeMap2 = {
410
+ sm: 24,
411
+ md: 32,
412
+ lg: 48,
413
+ xl: 64
414
+ };
415
+ var fontSizeMap = {
416
+ sm: 10,
417
+ md: 13,
418
+ lg: 18,
419
+ xl: 24
420
+ };
421
+ function Avatar({ src, fallback, size = "md", style }) {
422
+ const { colors } = useTheme();
423
+ const [imageError, setImageError] = useState(false);
424
+ const dimension = sizeMap2[size];
425
+ const showFallback = !src || imageError;
426
+ const containerStyle = {
427
+ width: dimension,
428
+ height: dimension,
429
+ borderRadius: dimension / 2,
430
+ backgroundColor: colors.muted,
431
+ overflow: "hidden"
432
+ };
433
+ return /* @__PURE__ */ React23.createElement(View, { style: [styles7.base, containerStyle, style] }, !showFallback ? /* @__PURE__ */ React23.createElement(
434
+ Image,
435
+ {
436
+ source: { uri: src },
437
+ style: { width: dimension, height: dimension },
438
+ onError: () => setImageError(true)
439
+ }
440
+ ) : /* @__PURE__ */ React23.createElement(
441
+ Text,
442
+ {
443
+ style: [styles7.fallback, { color: colors.mutedForeground, fontSize: fontSizeMap[size] }]
444
+ },
445
+ fallback?.slice(0, 2).toUpperCase() ?? "?"
446
+ ));
447
+ }
448
+ var styles7 = StyleSheet.create({
449
+ base: {
450
+ alignItems: "center",
451
+ justifyContent: "center"
452
+ },
453
+ fallback: {
454
+ fontWeight: "500"
455
+ }
456
+ });
457
+ function Alert({ title, description, variant = "default", icon, style }) {
458
+ const { colors } = useTheme();
459
+ const borderColor = variant === "destructive" ? colors.destructive : colors.border;
460
+ const titleColor = variant === "destructive" ? colors.destructive : colors.foreground;
461
+ const descColor = variant === "destructive" ? colors.destructive : colors.mutedForeground;
462
+ return /* @__PURE__ */ React23.createElement(View, { style: [styles8.container, { backgroundColor: colors.card, borderColor }, style] }, icon ? /* @__PURE__ */ React23.createElement(View, { style: styles8.icon }, icon) : null, /* @__PURE__ */ React23.createElement(View, { style: styles8.content }, title ? /* @__PURE__ */ React23.createElement(Text, { style: [styles8.title, { color: titleColor }] }, title) : null, description ? /* @__PURE__ */ React23.createElement(Text, { style: [styles8.description, { color: descColor }] }, description) : null));
463
+ }
464
+ var styles8 = StyleSheet.create({
465
+ container: {
466
+ flexDirection: "row",
467
+ borderWidth: 1,
468
+ borderRadius: 8,
469
+ padding: 16,
470
+ gap: 12
471
+ },
472
+ icon: {
473
+ marginTop: 2
474
+ },
475
+ content: {
476
+ flex: 1,
477
+ gap: 4
478
+ },
479
+ title: {
480
+ fontSize: 14,
481
+ fontWeight: "500",
482
+ lineHeight: 20
483
+ },
484
+ description: {
485
+ fontSize: 14,
486
+ lineHeight: 20
487
+ }
488
+ });
489
+ function Progress({ value = 0, max = 100, style }) {
490
+ const { colors } = useTheme();
491
+ const percent = Math.min(Math.max(value / max * 100, 0), 100);
492
+ const [trackWidth, setTrackWidth] = useState(0);
493
+ const animatedWidth = useRef(new Animated.Value(0)).current;
494
+ useEffect(() => {
495
+ if (trackWidth === 0) return;
496
+ Animated.spring(animatedWidth, {
497
+ toValue: percent / 100 * trackWidth,
498
+ useNativeDriver: false,
499
+ speed: 20,
500
+ bounciness: 0
501
+ }).start();
502
+ }, [percent, trackWidth]);
503
+ return /* @__PURE__ */ React23.createElement(
504
+ View,
505
+ {
506
+ style: [styles9.track, { backgroundColor: colors.muted }, style],
507
+ onLayout: (e) => setTrackWidth(e.nativeEvent.layout.width)
508
+ },
509
+ /* @__PURE__ */ React23.createElement(
510
+ Animated.View,
511
+ {
512
+ style: [styles9.indicator, { width: animatedWidth, backgroundColor: colors.primary }]
513
+ }
514
+ )
515
+ );
516
+ }
517
+ var styles9 = StyleSheet.create({
518
+ track: {
519
+ height: 8,
520
+ borderRadius: 999,
521
+ overflow: "hidden",
522
+ width: "100%"
523
+ },
524
+ indicator: {
525
+ height: "100%",
526
+ borderRadius: 999
527
+ }
528
+ });
529
+ function EmptyState({ icon, title, description, action, style }) {
530
+ const { colors } = useTheme();
531
+ return /* @__PURE__ */ React23.createElement(View, { style: [styles10.container, { borderColor: colors.border }, style] }, icon ? /* @__PURE__ */ React23.createElement(View, { style: [styles10.iconWrapper, { backgroundColor: colors.muted }] }, icon) : null, /* @__PURE__ */ React23.createElement(View, { style: styles10.textWrapper }, /* @__PURE__ */ React23.createElement(Text, { style: [styles10.title, { color: colors.foreground }] }, title), description ? /* @__PURE__ */ React23.createElement(Text, { style: [styles10.description, { color: colors.mutedForeground }] }, description) : null), action ? /* @__PURE__ */ React23.createElement(View, { style: styles10.action }, action) : null);
532
+ }
533
+ var styles10 = StyleSheet.create({
534
+ container: {
535
+ alignItems: "center",
536
+ justifyContent: "center",
537
+ borderWidth: 1,
538
+ borderStyle: "dashed",
539
+ borderRadius: 12,
540
+ padding: 32,
541
+ gap: 16
542
+ },
543
+ iconWrapper: {
544
+ width: 48,
545
+ height: 48,
546
+ borderRadius: 12,
547
+ alignItems: "center",
548
+ justifyContent: "center"
549
+ },
550
+ textWrapper: {
551
+ alignItems: "center",
552
+ gap: 8,
553
+ maxWidth: 320
554
+ },
555
+ title: {
556
+ fontSize: 18,
557
+ fontWeight: "500",
558
+ textAlign: "center"
559
+ },
560
+ description: {
561
+ fontSize: 14,
562
+ lineHeight: 20,
563
+ textAlign: "center"
564
+ },
565
+ action: {
566
+ marginTop: 8
567
+ }
568
+ });
569
+ function Textarea({
570
+ label,
571
+ error,
572
+ hint,
573
+ rows = 4,
574
+ containerStyle,
575
+ style,
576
+ onFocus,
577
+ onBlur,
578
+ ...props
579
+ }) {
580
+ const { colors } = useTheme();
581
+ const [focused, setFocused] = useState(false);
582
+ return /* @__PURE__ */ React23.createElement(View, { style: [styles11.container, containerStyle] }, label ? /* @__PURE__ */ React23.createElement(Text, { style: [styles11.label, { color: colors.foreground }], allowFontScaling: true }, label) : null, /* @__PURE__ */ React23.createElement(
583
+ TextInput,
584
+ {
585
+ multiline: true,
586
+ numberOfLines: rows,
587
+ textAlignVertical: "top",
588
+ style: [
589
+ styles11.input,
590
+ {
591
+ borderColor: error ? colors.destructive : focused ? colors.ring : colors.border,
592
+ color: colors.foreground,
593
+ backgroundColor: colors.background,
594
+ minHeight: rows * 28
595
+ },
596
+ style
597
+ ],
598
+ onFocus: (e) => {
599
+ setFocused(true);
600
+ onFocus?.(e);
601
+ },
602
+ onBlur: (e) => {
603
+ setFocused(false);
604
+ onBlur?.(e);
605
+ },
606
+ placeholderTextColor: colors.mutedForeground,
607
+ allowFontScaling: true,
608
+ ...props
609
+ }
610
+ ), error ? /* @__PURE__ */ React23.createElement(Text, { style: [styles11.helperText, { color: colors.destructive }], allowFontScaling: true }, error) : null, !error && hint ? /* @__PURE__ */ React23.createElement(Text, { style: [styles11.helperText, { color: colors.mutedForeground }], allowFontScaling: true }, hint) : null);
611
+ }
612
+ var styles11 = StyleSheet.create({
613
+ container: {
614
+ gap: 4
615
+ },
616
+ label: {
617
+ fontSize: 14,
618
+ fontWeight: "500",
619
+ marginBottom: 4
130
620
  },
131
621
  input: {
132
622
  borderWidth: 1.5,
133
- borderColor: "#D1D5DB",
134
623
  borderRadius: 8,
624
+ paddingHorizontal: 16,
625
+ paddingVertical: 14,
626
+ fontSize: 16
627
+ },
628
+ helperText: {
629
+ fontSize: 12
630
+ }
631
+ });
632
+ function Checkbox({
633
+ checked = false,
634
+ onCheckedChange,
635
+ label,
636
+ disabled,
637
+ style
638
+ }) {
639
+ const { colors } = useTheme();
640
+ const scale = useRef(new Animated.Value(1)).current;
641
+ const handlePressIn = () => {
642
+ if (disabled) return;
643
+ Animated.spring(scale, { toValue: 0.95, useNativeDriver: true, speed: 40, bounciness: 0 }).start();
644
+ };
645
+ const handlePressOut = () => {
646
+ Animated.spring(scale, { toValue: 1, useNativeDriver: true, speed: 40, bounciness: 4 }).start();
647
+ };
648
+ return /* @__PURE__ */ React23.createElement(Animated.View, { style: { transform: [{ scale }] } }, /* @__PURE__ */ React23.createElement(
649
+ TouchableOpacity,
650
+ {
651
+ style: [styles12.row, style],
652
+ onPress: () => {
653
+ Haptics11.selectionAsync();
654
+ onCheckedChange?.(!checked);
655
+ },
656
+ onPressIn: handlePressIn,
657
+ onPressOut: handlePressOut,
658
+ disabled,
659
+ activeOpacity: 1,
660
+ touchSoundDisabled: true
661
+ },
662
+ /* @__PURE__ */ React23.createElement(
663
+ View,
664
+ {
665
+ style: [
666
+ styles12.box,
667
+ {
668
+ borderColor: checked ? colors.primary : colors.border,
669
+ backgroundColor: checked ? colors.primary : "transparent",
670
+ opacity: disabled ? 0.45 : 1
671
+ }
672
+ ]
673
+ },
674
+ checked ? /* @__PURE__ */ React23.createElement(View, { style: [styles12.checkmark, { borderColor: colors.primaryForeground }] }) : null
675
+ ),
676
+ label ? /* @__PURE__ */ React23.createElement(
677
+ Text,
678
+ {
679
+ style: [styles12.label, { color: disabled ? colors.mutedForeground : colors.foreground }]
680
+ },
681
+ label
682
+ ) : null
683
+ ));
684
+ }
685
+ var styles12 = StyleSheet.create({
686
+ row: {
687
+ flexDirection: "row",
688
+ alignItems: "center",
689
+ gap: 10
690
+ },
691
+ box: {
692
+ width: 24,
693
+ height: 24,
694
+ borderRadius: 6,
695
+ borderWidth: 1.5,
696
+ alignItems: "center",
697
+ justifyContent: "center"
698
+ },
699
+ checkmark: {
700
+ width: 13,
701
+ height: 8,
702
+ borderLeftWidth: 2,
703
+ borderBottomWidth: 2,
704
+ transform: [{ rotate: "-45deg" }, { translateY: -1 }]
705
+ },
706
+ label: {
707
+ fontSize: 14,
708
+ lineHeight: 20
709
+ }
710
+ });
711
+ var TRACK_WIDTH = 56;
712
+ var TRACK_HEIGHT = 32;
713
+ var THUMB_SIZE = 24;
714
+ var THUMB_OFFSET = 4;
715
+ var THUMB_TRAVEL = TRACK_WIDTH - THUMB_SIZE - THUMB_OFFSET * 2;
716
+ function Switch({ checked = false, onCheckedChange, disabled, style }) {
717
+ const { colors } = useTheme();
718
+ const translateX = useRef(new Animated.Value(checked ? THUMB_TRAVEL : 0)).current;
719
+ const trackOpacity = useRef(new Animated.Value(checked ? 1 : 0)).current;
720
+ useEffect(() => {
721
+ Animated.parallel([
722
+ Animated.spring(translateX, {
723
+ toValue: checked ? THUMB_TRAVEL : 0,
724
+ useNativeDriver: true,
725
+ bounciness: 4
726
+ }),
727
+ Animated.timing(trackOpacity, {
728
+ toValue: checked ? 1 : 0,
729
+ duration: 150,
730
+ useNativeDriver: false
731
+ })
732
+ ]).start();
733
+ }, [checked, translateX, trackOpacity]);
734
+ const trackColor = trackOpacity.interpolate({
735
+ inputRange: [0, 1],
736
+ outputRange: [colors.muted, colors.primary]
737
+ });
738
+ return /* @__PURE__ */ React23.createElement(
739
+ TouchableOpacity,
740
+ {
741
+ onPress: () => {
742
+ Haptics11.selectionAsync();
743
+ onCheckedChange?.(!checked);
744
+ },
745
+ disabled,
746
+ activeOpacity: 0.8,
747
+ touchSoundDisabled: true,
748
+ style: [styles13.wrapper, { opacity: disabled ? 0.45 : 1 }, style]
749
+ },
750
+ /* @__PURE__ */ React23.createElement(Animated.View, { style: [styles13.track, { backgroundColor: trackColor }] }, /* @__PURE__ */ React23.createElement(
751
+ Animated.View,
752
+ {
753
+ style: [
754
+ styles13.thumb,
755
+ { backgroundColor: colors.primaryForeground, transform: [{ translateX }] }
756
+ ]
757
+ }
758
+ ))
759
+ );
760
+ }
761
+ var styles13 = StyleSheet.create({
762
+ wrapper: {},
763
+ track: {
764
+ width: TRACK_WIDTH,
765
+ height: TRACK_HEIGHT,
766
+ borderRadius: TRACK_HEIGHT / 2,
767
+ justifyContent: "center",
768
+ paddingHorizontal: THUMB_OFFSET
769
+ },
770
+ thumb: {
771
+ width: THUMB_SIZE,
772
+ height: THUMB_SIZE,
773
+ borderRadius: THUMB_SIZE / 2,
774
+ shadowColor: "#000",
775
+ shadowOffset: { width: 0, height: 1 },
776
+ shadowOpacity: 0.15,
777
+ shadowRadius: 2,
778
+ elevation: 2
779
+ }
780
+ });
781
+ var sizeStyles = {
782
+ sm: { paddingHorizontal: 12, paddingVertical: 8, minWidth: 40, minHeight: 40 },
783
+ md: { paddingHorizontal: 16, paddingVertical: 12, minWidth: 44, minHeight: 44 },
784
+ lg: { paddingHorizontal: 20, paddingVertical: 14, minWidth: 48, minHeight: 48 }
785
+ };
786
+ function Toggle({
787
+ pressed = false,
788
+ onPressedChange,
789
+ variant = "default",
790
+ size = "md",
791
+ label,
792
+ icon,
793
+ disabled,
794
+ style,
795
+ ...props
796
+ }) {
797
+ const { colors } = useTheme();
798
+ const scale = useRef(new Animated.Value(1)).current;
799
+ const handlePressIn = () => {
800
+ if (disabled) return;
801
+ Animated.spring(scale, { toValue: 0.95, useNativeDriver: true, speed: 40, bounciness: 0 }).start();
802
+ };
803
+ const handlePressOut = () => {
804
+ Animated.spring(scale, { toValue: 1, useNativeDriver: true, speed: 40, bounciness: 4 }).start();
805
+ };
806
+ const containerStyle = pressed ? { backgroundColor: colors.accent } : variant === "outline" ? { backgroundColor: "transparent", borderWidth: 1, borderColor: colors.border } : { backgroundColor: "transparent" };
807
+ const textColor = pressed ? colors.accentForeground : colors.foreground;
808
+ return /* @__PURE__ */ React23.createElement(Animated.View, { style: { transform: [{ scale }] } }, /* @__PURE__ */ React23.createElement(
809
+ TouchableOpacity,
810
+ {
811
+ style: [styles14.base, containerStyle, sizeStyles[size], disabled && styles14.disabled, style],
812
+ onPress: () => {
813
+ Haptics11.selectionAsync();
814
+ onPressedChange?.(!pressed);
815
+ },
816
+ onPressIn: handlePressIn,
817
+ onPressOut: handlePressOut,
818
+ disabled,
819
+ activeOpacity: 1,
820
+ touchSoundDisabled: true,
821
+ ...props
822
+ },
823
+ icon,
824
+ label ? /* @__PURE__ */ React23.createElement(Text, { style: [styles14.label, { color: textColor }] }, label) : null
825
+ ));
826
+ }
827
+ var styles14 = StyleSheet.create({
828
+ base: {
829
+ borderRadius: 8,
830
+ flexDirection: "row",
831
+ alignItems: "center",
832
+ justifyContent: "center",
833
+ gap: 8
834
+ },
835
+ disabled: {
836
+ opacity: 0.45
837
+ },
838
+ label: {
839
+ fontSize: 14,
840
+ fontWeight: "500"
841
+ }
842
+ });
843
+ function RadioItem({
844
+ option,
845
+ selected,
846
+ onSelect
847
+ }) {
848
+ const { colors } = useTheme();
849
+ const scale = useRef(new Animated.Value(1)).current;
850
+ const handlePressIn = () => {
851
+ if (option.disabled) return;
852
+ Animated.spring(scale, { toValue: 0.95, useNativeDriver: true, speed: 40, bounciness: 0 }).start();
853
+ };
854
+ const handlePressOut = () => {
855
+ Animated.spring(scale, { toValue: 1, useNativeDriver: true, speed: 40, bounciness: 4 }).start();
856
+ };
857
+ return /* @__PURE__ */ React23.createElement(Animated.View, { style: { transform: [{ scale }] } }, /* @__PURE__ */ React23.createElement(
858
+ TouchableOpacity,
859
+ {
860
+ style: styles15.row,
861
+ onPress: () => {
862
+ if (!option.disabled) {
863
+ Haptics11.selectionAsync();
864
+ onSelect();
865
+ }
866
+ },
867
+ onPressIn: handlePressIn,
868
+ onPressOut: handlePressOut,
869
+ activeOpacity: 1,
870
+ touchSoundDisabled: true,
871
+ disabled: option.disabled
872
+ },
873
+ /* @__PURE__ */ React23.createElement(
874
+ View,
875
+ {
876
+ style: [
877
+ styles15.radio,
878
+ {
879
+ borderColor: selected ? colors.primary : colors.border,
880
+ opacity: option.disabled ? 0.45 : 1
881
+ }
882
+ ]
883
+ },
884
+ selected ? /* @__PURE__ */ React23.createElement(View, { style: [styles15.dot, { backgroundColor: colors.primary }] }) : null
885
+ ),
886
+ /* @__PURE__ */ React23.createElement(
887
+ Text,
888
+ {
889
+ style: [
890
+ styles15.label,
891
+ { color: option.disabled ? colors.mutedForeground : colors.foreground }
892
+ ]
893
+ },
894
+ option.label
895
+ )
896
+ ));
897
+ }
898
+ function RadioGroup({
899
+ options,
900
+ value,
901
+ onValueChange,
902
+ orientation = "vertical",
903
+ style
904
+ }) {
905
+ return /* @__PURE__ */ React23.createElement(View, { style: [styles15.container, orientation === "horizontal" && styles15.horizontal, style] }, options.map((option) => /* @__PURE__ */ React23.createElement(
906
+ RadioItem,
907
+ {
908
+ key: option.value,
909
+ option,
910
+ selected: option.value === value,
911
+ onSelect: () => onValueChange?.(option.value)
912
+ }
913
+ )));
914
+ }
915
+ var styles15 = StyleSheet.create({
916
+ container: {
917
+ gap: 10
918
+ },
919
+ horizontal: {
920
+ flexDirection: "row",
921
+ flexWrap: "wrap"
922
+ },
923
+ row: {
924
+ flexDirection: "row",
925
+ alignItems: "center",
926
+ gap: 10
927
+ },
928
+ radio: {
929
+ width: 24,
930
+ height: 24,
931
+ borderRadius: 12,
932
+ borderWidth: 1.5,
933
+ alignItems: "center",
934
+ justifyContent: "center"
935
+ },
936
+ dot: {
937
+ width: 10,
938
+ height: 10,
939
+ borderRadius: 5
940
+ },
941
+ label: {
942
+ fontSize: 14,
943
+ lineHeight: 20
944
+ }
945
+ });
946
+ function TabTrigger({
947
+ tab,
948
+ isActive,
949
+ onPress,
950
+ onLayout
951
+ }) {
952
+ const { colors } = useTheme();
953
+ const scale = useRef(new Animated.Value(1)).current;
954
+ const handlePressIn = () => {
955
+ Animated.spring(scale, { toValue: 0.95, useNativeDriver: true, speed: 40, bounciness: 0 }).start();
956
+ };
957
+ const handlePressOut = () => {
958
+ Animated.spring(scale, { toValue: 1, useNativeDriver: true, speed: 40, bounciness: 4 }).start();
959
+ };
960
+ return /* @__PURE__ */ React23.createElement(
961
+ TouchableOpacity,
962
+ {
963
+ style: styles16.trigger,
964
+ onPress,
965
+ onPressIn: handlePressIn,
966
+ onPressOut: handlePressOut,
967
+ onLayout,
968
+ activeOpacity: 1,
969
+ touchSoundDisabled: true
970
+ },
971
+ /* @__PURE__ */ React23.createElement(Animated.View, { style: { transform: [{ scale }] } }, /* @__PURE__ */ React23.createElement(
972
+ Text,
973
+ {
974
+ style: [
975
+ styles16.triggerLabel,
976
+ { color: isActive ? colors.foreground : colors.mutedForeground },
977
+ isActive && styles16.activeTriggerLabel
978
+ ]
979
+ },
980
+ tab.label
981
+ ))
982
+ );
983
+ }
984
+ function Tabs({ tabs, value, onValueChange, children, style }) {
985
+ const [internal, setInternal] = useState(tabs[0]?.value ?? "");
986
+ const { colors } = useTheme();
987
+ const active = value ?? internal;
988
+ const tabLayouts = useRef({});
989
+ const pillX = useRef(new Animated.Value(0)).current;
990
+ const pillWidth = useRef(new Animated.Value(0)).current;
991
+ const initialised = useRef(false);
992
+ const animatePill = (tabValue, animate) => {
993
+ const layout = tabLayouts.current[tabValue];
994
+ if (!layout) return;
995
+ if (animate) {
996
+ Animated.parallel([
997
+ Animated.spring(pillX, {
998
+ toValue: layout.x,
999
+ useNativeDriver: false,
1000
+ speed: 20,
1001
+ bounciness: 0
1002
+ }),
1003
+ Animated.spring(pillWidth, {
1004
+ toValue: layout.width,
1005
+ useNativeDriver: false,
1006
+ speed: 20,
1007
+ bounciness: 0
1008
+ })
1009
+ ]).start();
1010
+ } else {
1011
+ pillX.setValue(layout.x);
1012
+ pillWidth.setValue(layout.width);
1013
+ }
1014
+ };
1015
+ useEffect(() => {
1016
+ if (initialised.current) {
1017
+ animatePill(active, true);
1018
+ }
1019
+ }, [active]);
1020
+ const handlePress = (v) => {
1021
+ Haptics11.selectionAsync();
1022
+ if (!value) setInternal(v);
1023
+ onValueChange?.(v);
1024
+ };
1025
+ return /* @__PURE__ */ React23.createElement(View, { style }, /* @__PURE__ */ React23.createElement(View, { style: [styles16.list, { backgroundColor: colors.muted }] }, /* @__PURE__ */ React23.createElement(
1026
+ Animated.View,
1027
+ {
1028
+ style: [
1029
+ styles16.pill,
1030
+ {
1031
+ backgroundColor: colors.background,
1032
+ position: "absolute",
1033
+ top: 4,
1034
+ bottom: 4,
1035
+ left: pillX,
1036
+ width: pillWidth,
1037
+ borderRadius: 6,
1038
+ shadowColor: "#000",
1039
+ shadowOffset: { width: 0, height: 1 },
1040
+ shadowOpacity: 0.1,
1041
+ shadowRadius: 2,
1042
+ elevation: 2
1043
+ }
1044
+ ]
1045
+ }
1046
+ ), tabs.map((tab) => /* @__PURE__ */ React23.createElement(
1047
+ TabTrigger,
1048
+ {
1049
+ key: tab.value,
1050
+ tab,
1051
+ isActive: tab.value === active,
1052
+ onPress: () => handlePress(tab.value),
1053
+ onLayout: (e) => {
1054
+ const { x, width } = e.nativeEvent.layout;
1055
+ tabLayouts.current[tab.value] = { x, width };
1056
+ if (tab.value === active) {
1057
+ animatePill(tab.value, false);
1058
+ initialised.current = true;
1059
+ }
1060
+ }
1061
+ }
1062
+ ))), children);
1063
+ }
1064
+ function TabsContent({ value, activeValue, children, style }) {
1065
+ if (value !== activeValue) return null;
1066
+ return /* @__PURE__ */ React23.createElement(View, { style }, children);
1067
+ }
1068
+ var styles16 = StyleSheet.create({
1069
+ list: {
1070
+ flexDirection: "row",
1071
+ borderRadius: 8,
1072
+ padding: 4,
1073
+ gap: 4
1074
+ },
1075
+ pill: {},
1076
+ trigger: {
1077
+ flex: 1,
1078
+ paddingVertical: 8,
135
1079
  paddingHorizontal: 12,
136
- paddingVertical: 10,
1080
+ borderRadius: 6,
1081
+ alignItems: "center",
1082
+ justifyContent: "center",
1083
+ zIndex: 1
1084
+ },
1085
+ triggerLabel: {
1086
+ fontSize: 14,
1087
+ fontWeight: "400"
1088
+ },
1089
+ activeTriggerLabel: {
1090
+ fontWeight: "500"
1091
+ }
1092
+ });
1093
+ function AccordionItemComponent({
1094
+ item,
1095
+ isOpen,
1096
+ onToggle
1097
+ }) {
1098
+ const { colors } = useTheme();
1099
+ const animatedHeight = useSharedValue(0);
1100
+ const animatedRotation = useSharedValue(0);
1101
+ const contentHeight = useRef(0);
1102
+ const scale = useRef(new Animated.Value(1)).current;
1103
+ const toggle = (open) => {
1104
+ const easing = open ? Easing.out(Easing.ease) : Easing.in(Easing.ease);
1105
+ animatedHeight.value = withTiming(open ? contentHeight.current : 0, { duration: 220, easing });
1106
+ animatedRotation.value = withTiming(open ? 1 : 0, { duration: 220, easing });
1107
+ };
1108
+ React23.useEffect(() => {
1109
+ toggle(isOpen);
1110
+ }, [isOpen]);
1111
+ const onLayout = (e) => {
1112
+ if (contentHeight.current === 0) {
1113
+ contentHeight.current = e.nativeEvent.layout.height;
1114
+ if (isOpen) animatedHeight.value = contentHeight.current;
1115
+ }
1116
+ };
1117
+ const heightStyle = useAnimatedStyle(() => ({
1118
+ height: animatedHeight.value,
1119
+ overflow: "hidden"
1120
+ }));
1121
+ const rotationStyle = useAnimatedStyle(() => ({
1122
+ transform: [{ rotate: `${animatedRotation.value * 180}deg` }]
1123
+ }));
1124
+ const handlePressIn = () => {
1125
+ Animated.spring(scale, { toValue: 0.95, useNativeDriver: true, speed: 40, bounciness: 0 }).start();
1126
+ };
1127
+ const handlePressOut = () => {
1128
+ Animated.spring(scale, { toValue: 1, useNativeDriver: true, speed: 40, bounciness: 4 }).start();
1129
+ };
1130
+ return /* @__PURE__ */ React23.createElement(View, { style: [styles17.item, { borderBottomColor: colors.border }] }, /* @__PURE__ */ React23.createElement(Animated.View, { style: { transform: [{ scale }] } }, /* @__PURE__ */ React23.createElement(
1131
+ TouchableOpacity,
1132
+ {
1133
+ style: styles17.trigger,
1134
+ onPress: () => {
1135
+ Haptics11.selectionAsync();
1136
+ onToggle();
1137
+ },
1138
+ onPressIn: handlePressIn,
1139
+ onPressOut: handlePressOut,
1140
+ activeOpacity: 1,
1141
+ touchSoundDisabled: true
1142
+ },
1143
+ /* @__PURE__ */ React23.createElement(Text, { style: [styles17.triggerText, { color: colors.foreground }] }, item.trigger),
1144
+ /* @__PURE__ */ React23.createElement(
1145
+ ReanimatedAnimated.Text,
1146
+ {
1147
+ style: [styles17.chevron, { color: colors.foreground }, rotationStyle]
1148
+ },
1149
+ "\u25BE"
1150
+ )
1151
+ )), /* @__PURE__ */ React23.createElement(ReanimatedAnimated.View, { style: heightStyle }, /* @__PURE__ */ React23.createElement(View, { style: styles17.content, onLayout }, item.content)));
1152
+ }
1153
+ function Accordion({ items, type = "single", defaultValue, style }) {
1154
+ const [openValues, setOpenValues] = useState(() => {
1155
+ if (!defaultValue) return [];
1156
+ return Array.isArray(defaultValue) ? defaultValue : [defaultValue];
1157
+ });
1158
+ const toggle = (value) => {
1159
+ if (type === "single") {
1160
+ setOpenValues((prev) => prev.includes(value) ? [] : [value]);
1161
+ } else {
1162
+ setOpenValues(
1163
+ (prev) => prev.includes(value) ? prev.filter((v) => v !== value) : [...prev, value]
1164
+ );
1165
+ }
1166
+ };
1167
+ return /* @__PURE__ */ React23.createElement(View, { style }, items.map((item) => /* @__PURE__ */ React23.createElement(
1168
+ AccordionItemComponent,
1169
+ {
1170
+ key: item.value,
1171
+ item,
1172
+ isOpen: openValues.includes(item.value),
1173
+ onToggle: () => toggle(item.value)
1174
+ }
1175
+ )));
1176
+ }
1177
+ var styles17 = StyleSheet.create({
1178
+ item: {
1179
+ borderBottomWidth: 1
1180
+ },
1181
+ trigger: {
1182
+ flexDirection: "row",
1183
+ justifyContent: "space-between",
1184
+ alignItems: "center",
1185
+ paddingVertical: 16
1186
+ },
1187
+ triggerText: {
137
1188
  fontSize: 15,
138
- color: "#111827",
139
- backgroundColor: "#fff"
1189
+ fontWeight: "500",
1190
+ flex: 1
140
1191
  },
141
- inputFocused: {
142
- borderColor: "#000"
1192
+ chevron: {
1193
+ fontSize: 16,
1194
+ marginLeft: 8
143
1195
  },
144
- inputError: {
145
- borderColor: "#EF4444"
1196
+ content: {
1197
+ paddingBottom: 16,
1198
+ position: "absolute",
1199
+ width: "100%"
1200
+ }
1201
+ });
1202
+ function Slider({
1203
+ value = 0,
1204
+ minimumValue = 0,
1205
+ maximumValue = 1,
1206
+ step = 0,
1207
+ onValueChange,
1208
+ onSlidingComplete,
1209
+ disabled,
1210
+ style
1211
+ }) {
1212
+ const { colors } = useTheme();
1213
+ const trackWidth = useRef(0);
1214
+ const lastSteppedValue = useRef(value);
1215
+ const [internalValue, setInternalValue] = useState(value);
1216
+ const currentValue = value ?? internalValue;
1217
+ const clamp = (v) => Math.min(Math.max(v, minimumValue), maximumValue);
1218
+ const snapToStep = (v) => {
1219
+ if (!step) return v;
1220
+ return Math.round((v - minimumValue) / step) * step + minimumValue;
1221
+ };
1222
+ const xToValue = (x) => {
1223
+ const ratio = Math.min(Math.max(x / trackWidth.current, 0), 1);
1224
+ const raw = ratio * (maximumValue - minimumValue) + minimumValue;
1225
+ return clamp(snapToStep(raw));
1226
+ };
1227
+ const panResponder = useRef(
1228
+ PanResponder.create({
1229
+ onStartShouldSetPanResponder: () => !disabled,
1230
+ onMoveShouldSetPanResponder: () => !disabled,
1231
+ onPanResponderGrant: (e) => {
1232
+ const x = e.nativeEvent.locationX;
1233
+ const newValue = xToValue(x);
1234
+ setInternalValue(newValue);
1235
+ onValueChange?.(newValue);
1236
+ },
1237
+ onPanResponderMove: (e) => {
1238
+ const x = e.nativeEvent.locationX;
1239
+ const newValue = xToValue(x);
1240
+ if (newValue !== lastSteppedValue.current) {
1241
+ lastSteppedValue.current = newValue;
1242
+ Haptics11.selectionAsync();
1243
+ }
1244
+ setInternalValue(newValue);
1245
+ onValueChange?.(newValue);
1246
+ },
1247
+ onPanResponderRelease: (e) => {
1248
+ const x = e.nativeEvent.locationX;
1249
+ const newValue = xToValue(x);
1250
+ setInternalValue(newValue);
1251
+ onSlidingComplete?.(newValue);
1252
+ }
1253
+ })
1254
+ ).current;
1255
+ const onLayout = (e) => {
1256
+ trackWidth.current = e.nativeEvent.layout.width;
1257
+ };
1258
+ const percent = (currentValue - minimumValue) / (maximumValue - minimumValue) * 100;
1259
+ return /* @__PURE__ */ React23.createElement(
1260
+ View,
1261
+ {
1262
+ style: [styles18.container, disabled && styles18.disabled, style],
1263
+ ...panResponder.panHandlers,
1264
+ onLayout
1265
+ },
1266
+ /* @__PURE__ */ React23.createElement(View, { style: [styles18.track, { backgroundColor: colors.muted }] }, /* @__PURE__ */ React23.createElement(
1267
+ View,
1268
+ {
1269
+ style: [styles18.range, { width: `${percent}%`, backgroundColor: colors.primary }]
1270
+ }
1271
+ )),
1272
+ /* @__PURE__ */ React23.createElement(
1273
+ View,
1274
+ {
1275
+ style: [
1276
+ styles18.thumb,
1277
+ {
1278
+ left: `${percent}%`,
1279
+ backgroundColor: colors.primary,
1280
+ borderColor: colors.background,
1281
+ transform: [{ translateX: -14 }]
1282
+ }
1283
+ ],
1284
+ pointerEvents: "none"
1285
+ }
1286
+ )
1287
+ );
1288
+ }
1289
+ var styles18 = StyleSheet.create({
1290
+ container: {
1291
+ height: 32,
1292
+ justifyContent: "center",
1293
+ position: "relative"
146
1294
  },
147
- errorText: {
148
- fontSize: 12,
149
- color: "#EF4444"
1295
+ disabled: {
1296
+ opacity: 0.45
150
1297
  },
151
- hintText: {
152
- fontSize: 12,
153
- color: "#6B7280"
1298
+ track: {
1299
+ height: 6,
1300
+ borderRadius: 3,
1301
+ overflow: "hidden",
1302
+ width: "100%"
1303
+ },
1304
+ range: {
1305
+ height: "100%",
1306
+ borderRadius: 3
1307
+ },
1308
+ thumb: {
1309
+ position: "absolute",
1310
+ width: 28,
1311
+ height: 28,
1312
+ borderRadius: 14,
1313
+ borderWidth: 2,
1314
+ shadowColor: "#000",
1315
+ shadowOffset: { width: 0, height: 1 },
1316
+ shadowOpacity: 0.2,
1317
+ shadowRadius: 2,
1318
+ elevation: 2
1319
+ }
1320
+ });
1321
+ function Sheet({
1322
+ open,
1323
+ onClose,
1324
+ title,
1325
+ description,
1326
+ children,
1327
+ snapPoints = ["50%"],
1328
+ style
1329
+ }) {
1330
+ const { colors } = useTheme();
1331
+ const ref = useRef(null);
1332
+ useEffect(() => {
1333
+ if (open) {
1334
+ Haptics11.impactAsync(Haptics11.ImpactFeedbackStyle.Light);
1335
+ ref.current?.present();
1336
+ } else {
1337
+ ref.current?.dismiss();
1338
+ }
1339
+ }, [open]);
1340
+ const renderBackdrop = (props) => /* @__PURE__ */ React23.createElement(
1341
+ BottomSheetBackdrop,
1342
+ {
1343
+ ...props,
1344
+ disappearsOnIndex: -1,
1345
+ appearsOnIndex: 0,
1346
+ pressBehavior: "close"
1347
+ }
1348
+ );
1349
+ return /* @__PURE__ */ React23.createElement(
1350
+ BottomSheetModal,
1351
+ {
1352
+ ref,
1353
+ snapPoints,
1354
+ onDismiss: onClose,
1355
+ backdropComponent: renderBackdrop,
1356
+ backgroundStyle: [styles19.background, { backgroundColor: colors.card }],
1357
+ handleIndicatorStyle: [styles19.handle, { backgroundColor: colors.border }],
1358
+ enablePanDownToClose: true
1359
+ },
1360
+ /* @__PURE__ */ React23.createElement(BottomSheetView, { style: [styles19.content, style] }, title || description ? /* @__PURE__ */ React23.createElement(View, { style: styles19.header }, title ? /* @__PURE__ */ React23.createElement(Text, { style: [styles19.title, { color: colors.cardForeground }] }, title) : null, description ? /* @__PURE__ */ React23.createElement(Text, { style: [styles19.description, { color: colors.mutedForeground }] }, description) : null) : null, children)
1361
+ );
1362
+ }
1363
+ var styles19 = StyleSheet.create({
1364
+ background: {
1365
+ borderTopLeftRadius: 16,
1366
+ borderTopRightRadius: 16
1367
+ },
1368
+ handle: {
1369
+ width: 36,
1370
+ height: 4,
1371
+ borderRadius: 2
1372
+ },
1373
+ content: {
1374
+ paddingHorizontal: 24,
1375
+ paddingBottom: 32
1376
+ },
1377
+ header: {
1378
+ gap: 8,
1379
+ marginBottom: 16
1380
+ },
1381
+ title: {
1382
+ fontSize: 18,
1383
+ fontWeight: "600"
1384
+ },
1385
+ description: {
1386
+ fontSize: 14,
1387
+ lineHeight: 20
1388
+ }
1389
+ });
1390
+ function Select({
1391
+ options,
1392
+ value,
1393
+ onValueChange,
1394
+ placeholder = "Select an option",
1395
+ label,
1396
+ error,
1397
+ disabled,
1398
+ style
1399
+ }) {
1400
+ const { colors } = useTheme();
1401
+ const bottomSheetRef = useRef(null);
1402
+ const scale = useRef(new Animated.Value(1)).current;
1403
+ const selected = options.find((o) => o.value === value);
1404
+ const handlePressIn = () => {
1405
+ if (disabled) return;
1406
+ Animated.spring(scale, { toValue: 0.95, useNativeDriver: true, speed: 40, bounciness: 0 }).start();
1407
+ };
1408
+ const handlePressOut = () => {
1409
+ Animated.spring(scale, { toValue: 1, useNativeDriver: true, speed: 40, bounciness: 4 }).start();
1410
+ };
1411
+ const handleOpen = () => {
1412
+ if (!disabled) {
1413
+ Haptics11.selectionAsync();
1414
+ bottomSheetRef.current?.present();
1415
+ }
1416
+ };
1417
+ const renderBackdrop = useCallback(
1418
+ (props) => /* @__PURE__ */ React23.createElement(
1419
+ BottomSheetBackdrop,
1420
+ {
1421
+ ...props,
1422
+ disappearsOnIndex: -1,
1423
+ appearsOnIndex: 0,
1424
+ pressBehavior: "close"
1425
+ }
1426
+ ),
1427
+ []
1428
+ );
1429
+ return /* @__PURE__ */ React23.createElement(View, { style: [styles20.container, style] }, label ? /* @__PURE__ */ React23.createElement(Text, { style: [styles20.label, { color: colors.foreground }] }, label) : null, /* @__PURE__ */ React23.createElement(Animated.View, { style: { transform: [{ scale }], opacity: disabled ? 0.45 : 1 } }, /* @__PURE__ */ React23.createElement(
1430
+ TouchableOpacity,
1431
+ {
1432
+ style: [
1433
+ styles20.trigger,
1434
+ {
1435
+ borderColor: error ? colors.destructive : colors.border,
1436
+ backgroundColor: colors.background
1437
+ }
1438
+ ],
1439
+ onPress: handleOpen,
1440
+ onPressIn: handlePressIn,
1441
+ onPressOut: handlePressOut,
1442
+ activeOpacity: 1,
1443
+ touchSoundDisabled: true
1444
+ },
1445
+ /* @__PURE__ */ React23.createElement(
1446
+ Text,
1447
+ {
1448
+ style: [
1449
+ styles20.triggerText,
1450
+ { color: selected ? colors.foreground : colors.mutedForeground }
1451
+ ],
1452
+ numberOfLines: 1
1453
+ },
1454
+ selected?.label ?? placeholder
1455
+ ),
1456
+ /* @__PURE__ */ React23.createElement(Text, { style: [styles20.chevron, { color: colors.mutedForeground }] }, "\u25BE")
1457
+ )), error ? /* @__PURE__ */ React23.createElement(Text, { style: [styles20.helperText, { color: colors.destructive }] }, error) : null, /* @__PURE__ */ React23.createElement(
1458
+ BottomSheetModal,
1459
+ {
1460
+ ref: bottomSheetRef,
1461
+ enableDynamicSizing: true,
1462
+ enablePanDownToClose: true,
1463
+ backdropComponent: renderBackdrop,
1464
+ backgroundStyle: [styles20.sheetBackground, { backgroundColor: colors.card }],
1465
+ handleIndicatorStyle: [styles20.sheetHandle, { backgroundColor: colors.border }]
1466
+ },
1467
+ /* @__PURE__ */ React23.createElement(BottomSheetView, { style: styles20.sheetContent }, label ? /* @__PURE__ */ React23.createElement(Text, { style: [styles20.sheetTitle, { color: colors.foreground }] }, label) : null, options.map((item) => {
1468
+ const isSelected = item.value === value;
1469
+ return /* @__PURE__ */ React23.createElement(
1470
+ TouchableOpacity,
1471
+ {
1472
+ key: item.value,
1473
+ style: [
1474
+ styles20.option,
1475
+ isSelected && { backgroundColor: colors.accent },
1476
+ item.disabled && styles20.disabledOption
1477
+ ],
1478
+ onPress: () => {
1479
+ if (!item.disabled) {
1480
+ Haptics11.selectionAsync();
1481
+ onValueChange?.(item.value);
1482
+ bottomSheetRef.current?.dismiss();
1483
+ }
1484
+ },
1485
+ activeOpacity: 0.7,
1486
+ touchSoundDisabled: true
1487
+ },
1488
+ /* @__PURE__ */ React23.createElement(
1489
+ Text,
1490
+ {
1491
+ style: [
1492
+ styles20.optionText,
1493
+ { color: item.disabled ? colors.mutedForeground : colors.foreground },
1494
+ isSelected && { fontWeight: "500" }
1495
+ ]
1496
+ },
1497
+ item.label
1498
+ ),
1499
+ isSelected ? /* @__PURE__ */ React23.createElement(Text, { style: [styles20.checkmark, { color: colors.primary }] }, "\u2713") : null
1500
+ );
1501
+ }))
1502
+ ));
1503
+ }
1504
+ var styles20 = StyleSheet.create({
1505
+ container: {
1506
+ gap: 4
1507
+ },
1508
+ label: {
1509
+ fontSize: 14,
1510
+ fontWeight: "500",
1511
+ marginBottom: 2
1512
+ },
1513
+ trigger: {
1514
+ flexDirection: "row",
1515
+ alignItems: "center",
1516
+ justifyContent: "space-between",
1517
+ borderWidth: 1.5,
1518
+ borderRadius: 8,
1519
+ paddingHorizontal: 16,
1520
+ paddingVertical: 14
1521
+ },
1522
+ triggerText: {
1523
+ fontSize: 16,
1524
+ flex: 1
1525
+ },
1526
+ chevron: {
1527
+ fontSize: 14,
1528
+ marginLeft: 8
1529
+ },
1530
+ helperText: {
1531
+ fontSize: 12
1532
+ },
1533
+ sheetBackground: {
1534
+ borderTopLeftRadius: 16,
1535
+ borderTopRightRadius: 16
1536
+ },
1537
+ sheetHandle: {
1538
+ width: 36,
1539
+ height: 4,
1540
+ borderRadius: 2
1541
+ },
1542
+ sheetContent: {
1543
+ paddingHorizontal: 16,
1544
+ paddingBottom: 32
1545
+ },
1546
+ sheetTitle: {
1547
+ fontSize: 16,
1548
+ fontWeight: "600",
1549
+ paddingVertical: 12,
1550
+ paddingHorizontal: 4
1551
+ },
1552
+ option: {
1553
+ flexDirection: "row",
1554
+ alignItems: "center",
1555
+ justifyContent: "space-between",
1556
+ paddingHorizontal: 12,
1557
+ paddingVertical: 14,
1558
+ borderRadius: 8
1559
+ },
1560
+ optionText: {
1561
+ fontSize: 15,
1562
+ flex: 1
1563
+ },
1564
+ disabledOption: {
1565
+ opacity: 0.45
1566
+ },
1567
+ checkmark: {
1568
+ fontSize: 14,
1569
+ fontWeight: "600",
1570
+ marginLeft: 8
1571
+ }
1572
+ });
1573
+ var ToastContext = createContext({
1574
+ toast: () => {
1575
+ },
1576
+ dismiss: () => {
1577
+ }
1578
+ });
1579
+ function useToast() {
1580
+ return useContext(ToastContext);
1581
+ }
1582
+ var SWIPE_THRESHOLD = 80;
1583
+ var VELOCITY_THRESHOLD = 800;
1584
+ function ToastNotification({ item, onDismiss }) {
1585
+ const { colors } = useTheme();
1586
+ const translateY = useSharedValue(-80);
1587
+ const translateX = useSharedValue(0);
1588
+ const opacity = useSharedValue(0);
1589
+ useEffect(() => {
1590
+ translateY.value = withTiming(0, { duration: 120, easing: Easing.out(Easing.exp) });
1591
+ opacity.value = withTiming(1, { duration: 100 });
1592
+ const timer = setTimeout(() => {
1593
+ translateY.value = withTiming(-80, { duration: 200 });
1594
+ opacity.value = withTiming(0, { duration: 200 }, (done) => {
1595
+ if (done) runOnJS(onDismiss)();
1596
+ });
1597
+ }, item.duration ?? 3e3);
1598
+ return () => clearTimeout(timer);
1599
+ }, []);
1600
+ const panGesture = Gesture.Pan().onUpdate((e) => {
1601
+ translateX.value = e.translationX;
1602
+ }).onEnd((e) => {
1603
+ const shouldDismiss = Math.abs(translateX.value) > SWIPE_THRESHOLD || Math.abs(e.velocityX) > VELOCITY_THRESHOLD;
1604
+ if (shouldDismiss) {
1605
+ const direction = translateX.value > 0 ? 1 : -1;
1606
+ translateX.value = withTiming(direction * 500, { duration: 200 }, (done) => {
1607
+ if (done) runOnJS(onDismiss)();
1608
+ });
1609
+ opacity.value = withTiming(0, { duration: 150 });
1610
+ } else {
1611
+ translateX.value = withSpring(0, { damping: 20, stiffness: 300 });
1612
+ }
1613
+ });
1614
+ const animatedStyle = useAnimatedStyle(() => ({
1615
+ opacity: opacity.value,
1616
+ transform: [{ translateY: translateY.value }, { translateX: translateX.value }]
1617
+ }));
1618
+ const bgColor = {
1619
+ default: colors.foreground,
1620
+ destructive: colors.destructive,
1621
+ success: colors.success
1622
+ }[item.variant ?? "default"];
1623
+ const textColor = {
1624
+ default: colors.background,
1625
+ destructive: colors.destructiveForeground,
1626
+ success: colors.successForeground
1627
+ }[item.variant ?? "default"];
1628
+ return /* @__PURE__ */ React23.createElement(GestureDetector, { gesture: panGesture }, /* @__PURE__ */ React23.createElement(ReanimatedAnimated.View, { style: [styles21.toast, { backgroundColor: bgColor }, animatedStyle] }, /* @__PURE__ */ React23.createElement(View, { style: styles21.toastContent }, item.title ? /* @__PURE__ */ React23.createElement(Text, { style: [styles21.toastTitle, { color: textColor }] }, item.title) : null, item.description ? /* @__PURE__ */ React23.createElement(Text, { style: [styles21.toastDescription, { color: textColor, opacity: 0.85 }] }, item.description) : null), /* @__PURE__ */ React23.createElement(TouchableOpacity, { onPress: onDismiss, style: styles21.dismissButton, touchSoundDisabled: true }, /* @__PURE__ */ React23.createElement(Text, { style: [styles21.dismissIcon, { color: textColor }] }, "\u2715"))));
1629
+ }
1630
+ function ToastProvider({ children }) {
1631
+ const [toasts, setToasts] = useState([]);
1632
+ const insets = useSafeAreaInsets();
1633
+ const toast = useCallback((item) => {
1634
+ const id = Math.random().toString(36).slice(2);
1635
+ if (item.variant === "success") {
1636
+ Haptics11.notificationAsync(Haptics11.NotificationFeedbackType.Success);
1637
+ } else if (item.variant === "destructive") {
1638
+ Haptics11.notificationAsync(Haptics11.NotificationFeedbackType.Error);
1639
+ } else {
1640
+ Haptics11.impactAsync(Haptics11.ImpactFeedbackStyle.Light);
1641
+ }
1642
+ setToasts((prev) => [{ ...item, id }, ...prev].slice(0, 3));
1643
+ }, []);
1644
+ const dismiss = useCallback((id) => {
1645
+ setToasts((prev) => prev.filter((t) => t.id !== id));
1646
+ }, []);
1647
+ return /* @__PURE__ */ React23.createElement(ToastContext.Provider, { value: { toast, dismiss } }, children, /* @__PURE__ */ React23.createElement(View, { style: [styles21.container, { top: insets.top + 8 }], pointerEvents: "box-none" }, toasts.map((item) => /* @__PURE__ */ React23.createElement(ToastNotification, { key: item.id, item, onDismiss: () => dismiss(item.id) }))));
1648
+ }
1649
+ var styles21 = StyleSheet.create({
1650
+ container: {
1651
+ position: "absolute",
1652
+ left: 16,
1653
+ right: 16,
1654
+ gap: 8,
1655
+ zIndex: 9999
1656
+ },
1657
+ toast: {
1658
+ flexDirection: "row",
1659
+ alignItems: "center",
1660
+ borderRadius: 12,
1661
+ paddingHorizontal: 16,
1662
+ paddingVertical: 12,
1663
+ shadowColor: "#000",
1664
+ shadowOffset: { width: 0, height: 4 },
1665
+ shadowOpacity: 0.15,
1666
+ shadowRadius: 8,
1667
+ elevation: 6
1668
+ },
1669
+ toastContent: {
1670
+ flex: 1,
1671
+ gap: 4
1672
+ },
1673
+ toastTitle: {
1674
+ fontSize: 14,
1675
+ fontWeight: "600"
1676
+ },
1677
+ toastDescription: {
1678
+ fontSize: 13
1679
+ },
1680
+ dismissButton: {
1681
+ padding: 12,
1682
+ marginLeft: 4
1683
+ },
1684
+ dismissIcon: {
1685
+ fontSize: 12
154
1686
  }
155
1687
  });
156
1688
 
157
- export { Button, Input, Text2 as Text };
1689
+ export { Accordion, Alert, Avatar, Badge, Button, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, EmptyState, Input, Progress, RadioGroup, Select, Separator, Sheet, Skeleton, Slider, Spinner, Switch, Tabs, TabsContent, Text2 as Text, Textarea, ThemeProvider, ToastProvider, Toggle, defaultDark, defaultLight, useTheme, useToast };