@beyondcorp/beyond-ui-native 0.1.1 → 0.1.3

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 (83) hide show
  1. package/dist/{chunk-2B6HTSGM.mjs → chunk-RNHEGFYR.mjs} +16 -2
  2. package/dist/chunk-RNHEGFYR.mjs.map +1 -0
  3. package/dist/index.d.mts +2 -145
  4. package/dist/index.d.ts +2 -145
  5. package/dist/index.js +37 -8
  6. package/dist/index.js.map +1 -1
  7. package/dist/index.mjs +23 -8
  8. package/dist/index.mjs.map +1 -1
  9. package/dist/preset-BmUHLoAa.d.mts +274 -0
  10. package/dist/preset-BmUHLoAa.d.ts +274 -0
  11. package/dist/preset.d.mts +1 -117
  12. package/dist/preset.d.ts +1 -117
  13. package/dist/preset.js +19 -3
  14. package/dist/preset.js.map +1 -1
  15. package/dist/preset.mjs +5 -3
  16. package/package.json +11 -5
  17. package/src/components/accordion/accordion.tsx +245 -0
  18. package/src/components/accordion/index.ts +1 -0
  19. package/src/components/alert/alert.tsx +118 -0
  20. package/src/components/alert/index.ts +1 -0
  21. package/src/components/avatar/avatar.tsx +125 -0
  22. package/src/components/avatar/index.ts +1 -0
  23. package/src/components/badge/badge.tsx +89 -0
  24. package/src/components/badge/index.ts +1 -0
  25. package/src/components/bottom-sheet/bottom-sheet.tsx +336 -0
  26. package/src/components/bottom-sheet/index.ts +1 -0
  27. package/src/components/button/button.tsx +172 -0
  28. package/src/components/button/index.ts +1 -0
  29. package/src/components/card/card.tsx +121 -0
  30. package/src/components/card/index.ts +1 -0
  31. package/src/components/checkbox/checkbox.tsx +100 -0
  32. package/src/components/checkbox/index.ts +1 -0
  33. package/src/components/data-table/data-table.tsx +277 -0
  34. package/src/components/data-table/index.ts +1 -0
  35. package/src/components/dialog/dialog.tsx +278 -0
  36. package/src/components/dialog/index.ts +1 -0
  37. package/src/components/input/index.ts +1 -0
  38. package/src/components/input/input.tsx +130 -0
  39. package/src/components/radio/index.ts +1 -0
  40. package/src/components/radio/radio.tsx +117 -0
  41. package/src/components/select/index.ts +1 -0
  42. package/src/components/select/select.tsx +375 -0
  43. package/src/components/separator/index.ts +1 -0
  44. package/src/components/separator/separator.tsx +28 -0
  45. package/src/components/skeleton/index.ts +1 -0
  46. package/src/components/skeleton/skeleton.tsx +43 -0
  47. package/src/components/spinner/index.ts +1 -0
  48. package/src/components/spinner/spinner.tsx +46 -0
  49. package/src/components/stats-card/index.ts +1 -0
  50. package/src/components/stats-card/stats-card.tsx +92 -0
  51. package/src/components/switch/index.ts +1 -0
  52. package/src/components/switch/switch.tsx +80 -0
  53. package/src/components/tabs/index.ts +1 -0
  54. package/src/components/tabs/tabs.tsx +172 -0
  55. package/src/components/text/heading.tsx +50 -0
  56. package/src/components/text/index.ts +2 -0
  57. package/src/components/text/text.tsx +62 -0
  58. package/src/components/textarea/index.ts +1 -0
  59. package/src/components/textarea/textarea.tsx +87 -0
  60. package/src/components/toast/index.ts +2 -0
  61. package/src/components/toast/toast.tsx +136 -0
  62. package/src/components/toast/types.ts +32 -0
  63. package/src/index.ts +42 -0
  64. package/src/primitives/box.tsx +25 -0
  65. package/src/primitives/index.ts +2 -0
  66. package/src/primitives/pressable.tsx +49 -0
  67. package/src/providers/BeyondUIProvider.tsx +100 -0
  68. package/src/templates/auth/ForgotPasswordTemplate.tsx +132 -0
  69. package/src/templates/auth/SignInTemplate.tsx +213 -0
  70. package/src/templates/auth/SignUpTemplate.tsx +233 -0
  71. package/src/templates/auth/index.ts +3 -0
  72. package/src/templates/dashboard/DashboardTemplate.tsx +205 -0
  73. package/src/templates/dashboard/index.ts +1 -0
  74. package/src/templates/index.ts +3 -0
  75. package/src/templates/settings/SettingsTemplate.tsx +226 -0
  76. package/src/templates/settings/index.ts +1 -0
  77. package/src/theme/preset.ts +45 -0
  78. package/src/theme/tokens.ts +144 -0
  79. package/src/types/nativewind-env.d.ts +26 -0
  80. package/src/utilities/accessibility.ts +43 -0
  81. package/src/utilities/cn.ts +9 -0
  82. package/src/utilities/index.ts +2 -0
  83. package/dist/chunk-2B6HTSGM.mjs.map +0 -1
@@ -0,0 +1,125 @@
1
+ import * as React from "react";
2
+ import { View, Text, Image as NativeImage, type ImageProps, type ViewProps } from "react-native";
3
+ import { cva, type VariantProps } from "class-variance-authority";
4
+ import { cn } from "../../utilities/cn";
5
+
6
+ export const avatarVariants = cva(
7
+ "relative flex shrink-0 overflow-hidden rounded-full items-center justify-center bg-neutral-200 dark:bg-neutral-800",
8
+ {
9
+ variants: {
10
+ size: {
11
+ sm: "h-8 w-8",
12
+ md: "h-10 w-10",
13
+ lg: "h-14 w-14",
14
+ xl: "h-20 w-20",
15
+ },
16
+ },
17
+ defaultVariants: {
18
+ size: "md",
19
+ },
20
+ }
21
+ );
22
+
23
+ export const avatarTextVariants = cva("font-semibold text-neutral-700 dark:text-neutral-300", {
24
+ variants: {
25
+ size: {
26
+ sm: "text-xs",
27
+ md: "text-sm",
28
+ lg: "text-lg",
29
+ xl: "text-2xl",
30
+ },
31
+ },
32
+ defaultVariants: {
33
+ size: "md",
34
+ },
35
+ });
36
+
37
+ interface AvatarContextValue {
38
+ size: "sm" | "md" | "lg" | "xl";
39
+ }
40
+
41
+ const AvatarContext = React.createContext<AvatarContextValue>({ size: "md" });
42
+
43
+ export interface AvatarProps
44
+ extends ViewProps,
45
+ VariantProps<typeof avatarVariants> {
46
+ className?: string;
47
+ }
48
+
49
+ export function Avatar({
50
+ className,
51
+ size = "md",
52
+ children,
53
+ ...props
54
+ }: AvatarProps) {
55
+ const currentSize = size ?? "md";
56
+ return (
57
+ <AvatarContext.Provider value={{ size: currentSize }}>
58
+ <View
59
+ className={cn(avatarVariants({ size: currentSize }), className)}
60
+ {...props}
61
+ >
62
+ {children}
63
+ </View>
64
+ </AvatarContext.Provider>
65
+ );
66
+ }
67
+ Avatar.displayName = "Avatar";
68
+
69
+ export interface AvatarImageProps extends ImageProps {
70
+ className?: string;
71
+ }
72
+
73
+ export function AvatarImage({ className, ...props }: AvatarImageProps) {
74
+ const [hasError, setHasError] = React.useState(false);
75
+
76
+ if (hasError) return null;
77
+
78
+ return (
79
+ <NativeImage
80
+ onError={() => setHasError(true)}
81
+ className={cn("h-full w-full rounded-full object-cover", className)}
82
+ {...props}
83
+ />
84
+ );
85
+ }
86
+ AvatarImage.displayName = "Avatar.Image";
87
+
88
+ export interface AvatarFallbackProps extends ViewProps {
89
+ children?: React.ReactNode;
90
+ text?: string;
91
+ className?: string;
92
+ textClassName?: string;
93
+ }
94
+
95
+ export function AvatarFallback({
96
+ children,
97
+ text,
98
+ className,
99
+ textClassName,
100
+ ...props
101
+ }: AvatarFallbackProps) {
102
+ const { size } = React.useContext(AvatarContext);
103
+ const content = text ?? children;
104
+
105
+ return (
106
+ <View
107
+ className={cn(
108
+ "h-full w-full items-center justify-center rounded-full bg-neutral-200 dark:bg-neutral-800",
109
+ className
110
+ )}
111
+ {...props}
112
+ >
113
+ {typeof content === "string" ? (
114
+ <Text
115
+ className={cn(avatarTextVariants({ size }), textClassName)}
116
+ >
117
+ {content}
118
+ </Text>
119
+ ) : (
120
+ content
121
+ )}
122
+ </View>
123
+ );
124
+ }
125
+ AvatarFallback.displayName = "Avatar.Fallback";
@@ -0,0 +1 @@
1
+ export * from "./avatar";
@@ -0,0 +1,89 @@
1
+ import * as React from "react";
2
+ import { View, Text, type ViewProps } from "react-native";
3
+ import { cva, type VariantProps } from "class-variance-authority";
4
+ import { cn } from "../../utilities/cn";
5
+
6
+ export const badgeVariants = cva(
7
+ "inline-flex flex-row items-center justify-center rounded-full self-start",
8
+ {
9
+ variants: {
10
+ variant: {
11
+ primary: "bg-primary-600 dark:bg-primary-500",
12
+ secondary: "bg-secondary-600 dark:bg-secondary-500",
13
+ danger: "bg-danger-600 dark:bg-danger-500",
14
+ destructive: "bg-danger-600 dark:bg-danger-500",
15
+ success: "bg-success-600 dark:bg-success-500",
16
+ warning: "bg-warning-600 dark:bg-warning-500",
17
+ outline: "border border-neutral-300 dark:border-neutral-700 bg-transparent",
18
+ },
19
+ size: {
20
+ sm: "px-2 py-0.5",
21
+ md: "px-2.5 py-1",
22
+ lg: "px-3.5 py-1.5",
23
+ },
24
+ },
25
+ defaultVariants: {
26
+ variant: "primary",
27
+ size: "md",
28
+ },
29
+ }
30
+ );
31
+
32
+ export const badgeTextVariants = cva("font-semibold text-center", {
33
+ variants: {
34
+ variant: {
35
+ primary: "text-white",
36
+ secondary: "text-white",
37
+ danger: "text-white",
38
+ destructive: "text-white",
39
+ success: "text-white",
40
+ warning: "text-white",
41
+ outline: "text-neutral-700 dark:text-neutral-300",
42
+ },
43
+ size: {
44
+ sm: "text-[10px]",
45
+ md: "text-xs",
46
+ lg: "text-sm",
47
+ },
48
+ },
49
+ defaultVariants: {
50
+ variant: "primary",
51
+ size: "md",
52
+ },
53
+ });
54
+
55
+ export interface BadgeProps
56
+ extends ViewProps,
57
+ VariantProps<typeof badgeVariants> {
58
+ children?: React.ReactNode;
59
+ className?: string;
60
+ textClassName?: string;
61
+ }
62
+
63
+ export function Badge({
64
+ children,
65
+ variant = "primary",
66
+ size = "md",
67
+ className,
68
+ textClassName,
69
+ ...props
70
+ }: BadgeProps) {
71
+ return (
72
+ <View
73
+ className={cn(badgeVariants({ variant, size }), className)}
74
+ {...props}
75
+ >
76
+ {typeof children === "string" || typeof children === "number" ? (
77
+ <Text
78
+ className={cn(badgeTextVariants({ variant, size }), textClassName)}
79
+ >
80
+ {children}
81
+ </Text>
82
+ ) : (
83
+ children
84
+ )}
85
+ </View>
86
+ );
87
+ }
88
+
89
+ Badge.displayName = "Badge";
@@ -0,0 +1 @@
1
+ export * from "./badge";
@@ -0,0 +1,336 @@
1
+ import * as React from "react";
2
+ import {
3
+ Modal,
4
+ View,
5
+ Pressable,
6
+ Animated,
7
+ PanResponder,
8
+ Dimensions,
9
+ type ViewProps,
10
+ type PressableProps,
11
+ } from "react-native";
12
+ import { cn } from "../../utilities/cn";
13
+ import { Text } from "../text/text";
14
+ import { Heading } from "../text/heading";
15
+
16
+ interface BottomSheetContextValue {
17
+ open: boolean;
18
+ setOpen: (open: boolean) => void;
19
+ closeSheet: () => void;
20
+ }
21
+
22
+ const BottomSheetContext = React.createContext<BottomSheetContextValue | null>(null);
23
+
24
+ function useBottomSheetContext() {
25
+ const context = React.useContext(BottomSheetContext);
26
+ if (!context) {
27
+ throw new Error("BottomSheet components must be used within a BottomSheet");
28
+ }
29
+ return context;
30
+ }
31
+
32
+ export interface BottomSheetProps {
33
+ open?: boolean;
34
+ defaultOpen?: boolean;
35
+ onOpenChange?: (open: boolean) => void;
36
+ children: React.ReactNode;
37
+ }
38
+
39
+ export const BottomSheet: React.FC<BottomSheetProps> = ({
40
+ open: controlledOpen,
41
+ defaultOpen = false,
42
+ onOpenChange,
43
+ children,
44
+ }) => {
45
+ const [uncontrolledOpen, setUncontrolledOpen] = React.useState(defaultOpen);
46
+ const isControlled = controlledOpen !== undefined;
47
+ const isOpen = isControlled ? controlledOpen : uncontrolledOpen;
48
+
49
+ const setOpen = React.useCallback(
50
+ (nextOpen: boolean) => {
51
+ if (!isControlled) {
52
+ setUncontrolledOpen(nextOpen);
53
+ }
54
+ onOpenChange?.(nextOpen);
55
+ },
56
+ [isControlled, onOpenChange]
57
+ );
58
+
59
+ const closeSheet = React.useCallback(() => {
60
+ setOpen(false);
61
+ }, [setOpen]);
62
+
63
+ return (
64
+ <BottomSheetContext.Provider value={{ open: isOpen, setOpen, closeSheet }}>
65
+ {children}
66
+ </BottomSheetContext.Provider>
67
+ );
68
+ };
69
+
70
+ // --- BottomSheetTrigger ---
71
+
72
+ export interface BottomSheetTriggerProps extends PressableProps {
73
+ asChild?: boolean;
74
+ className?: string;
75
+ children: React.ReactNode;
76
+ }
77
+
78
+ export const BottomSheetTrigger = React.forwardRef<View, BottomSheetTriggerProps>(
79
+ ({ asChild, children, onPress, ...props }, ref) => {
80
+ const { setOpen } = useBottomSheetContext();
81
+
82
+ const handlePress = (e: any) => {
83
+ setOpen(true);
84
+ onPress?.(e);
85
+ };
86
+
87
+ if (asChild && React.isValidElement(children)) {
88
+ return React.cloneElement(children as React.ReactElement<any>, {
89
+ ref,
90
+ onPress: handlePress,
91
+ });
92
+ }
93
+
94
+ return (
95
+ <Pressable ref={ref} onPress={handlePress} {...props}>
96
+ {children}
97
+ </Pressable>
98
+ );
99
+ }
100
+ );
101
+ BottomSheetTrigger.displayName = "BottomSheetTrigger";
102
+
103
+ // --- BottomSheetContent ---
104
+
105
+ export interface BottomSheetContentProps extends ViewProps {
106
+ className?: string;
107
+ children: React.ReactNode;
108
+ }
109
+
110
+ export const BottomSheetContent = React.forwardRef<View, BottomSheetContentProps>(
111
+ ({ className, children, ...props }, ref) => {
112
+ const { open, closeSheet } = useBottomSheetContext();
113
+ const screenHeight = Dimensions.get("window").height;
114
+
115
+ const translateY = React.useRef(new Animated.Value(screenHeight)).current;
116
+ const backdropOpacity = React.useRef(new Animated.Value(0)).current;
117
+
118
+ React.useEffect(() => {
119
+ if (open) {
120
+ Animated.parallel([
121
+ Animated.spring(translateY, {
122
+ toValue: 0,
123
+ useNativeDriver: true,
124
+ bounciness: 4,
125
+ }),
126
+ Animated.timing(backdropOpacity, {
127
+ toValue: 1,
128
+ duration: 250,
129
+ useNativeDriver: true,
130
+ }),
131
+ ]).start();
132
+ } else {
133
+ Animated.parallel([
134
+ Animated.timing(translateY, {
135
+ toValue: screenHeight,
136
+ duration: 200,
137
+ useNativeDriver: true,
138
+ }),
139
+ Animated.timing(backdropOpacity, {
140
+ toValue: 0,
141
+ duration: 200,
142
+ useNativeDriver: true,
143
+ }),
144
+ ]).start();
145
+ }
146
+ }, [open, translateY, backdropOpacity, screenHeight]);
147
+
148
+ // PanResponder for drag down to dismiss
149
+ const panResponder = React.useRef(
150
+ PanResponder.create({
151
+ onStartShouldSetPanResponder: () => true,
152
+ onMoveShouldSetPanResponder: (_, gestureState) => gestureState.dy > 5,
153
+ onPanResponderMove: (_, gestureState) => {
154
+ if (gestureState.dy > 0) {
155
+ translateY.setValue(gestureState.dy);
156
+ }
157
+ },
158
+ onPanResponderRelease: (_, gestureState) => {
159
+ if (gestureState.dy > 120 || gestureState.vy > 0.8) {
160
+ closeSheet();
161
+ } else {
162
+ Animated.spring(translateY, {
163
+ toValue: 0,
164
+ useNativeDriver: true,
165
+ bounciness: 4,
166
+ }).start();
167
+ }
168
+ },
169
+ })
170
+ ).current;
171
+
172
+ if (!open) return null;
173
+
174
+ return (
175
+ <Modal
176
+ transparent
177
+ visible={open}
178
+ animationType="none"
179
+ onRequestClose={closeSheet}
180
+ statusBarTranslucent
181
+ >
182
+ <View className="flex-1 justify-end">
183
+ {/* Backdrop */}
184
+ <Animated.View
185
+ style={{ opacity: backdropOpacity }}
186
+ className="absolute inset-0 bg-black/60"
187
+ >
188
+ <Pressable className="flex-1" onPress={closeSheet} />
189
+ </Animated.View>
190
+
191
+ {/* Sheet Container */}
192
+ <Animated.View
193
+ ref={ref}
194
+ style={{ transform: [{ translateY }] }}
195
+ className={cn(
196
+ "w-full bg-card rounded-t-3xl border-t border-border shadow-2xl pt-2 pb-8 px-6 max-h-[85%]",
197
+ className
198
+ )}
199
+ {...props}
200
+ >
201
+ {/* Drag Handle Bar */}
202
+ <View {...panResponder.panHandlers} className="w-full py-2 items-center">
203
+ <View className="w-12 h-1.5 rounded-full bg-muted/40" />
204
+ </View>
205
+
206
+ {children}
207
+ </Animated.View>
208
+ </View>
209
+ </Modal>
210
+ );
211
+ }
212
+ );
213
+ BottomSheetContent.displayName = "BottomSheetContent";
214
+
215
+ // --- BottomSheetHeader ---
216
+
217
+ export interface BottomSheetHeaderProps extends ViewProps {
218
+ className?: string;
219
+ children: React.ReactNode;
220
+ }
221
+
222
+ export const BottomSheetHeader = React.forwardRef<View, BottomSheetHeaderProps>(
223
+ ({ className, children, ...props }, ref) => (
224
+ <View ref={ref} className={cn("mb-4 gap-1", className)} {...props}>
225
+ {children}
226
+ </View>
227
+ )
228
+ );
229
+ BottomSheetHeader.displayName = "BottomSheetHeader";
230
+
231
+ // --- BottomSheetTitle ---
232
+
233
+ export interface BottomSheetTitleProps {
234
+ className?: string;
235
+ children: React.ReactNode;
236
+ }
237
+
238
+ export const BottomSheetTitle: React.FC<BottomSheetTitleProps> = ({
239
+ className,
240
+ children,
241
+ }) => {
242
+ return (
243
+ <Heading level={4} className={cn("text-xl font-bold text-foreground", className)}>
244
+ {children}
245
+ </Heading>
246
+ );
247
+ };
248
+ BottomSheetTitle.displayName = "BottomSheetTitle";
249
+
250
+ // --- BottomSheetDescription ---
251
+
252
+ export interface BottomSheetDescriptionProps {
253
+ className?: string;
254
+ children: React.ReactNode;
255
+ }
256
+
257
+ export const BottomSheetDescription: React.FC<BottomSheetDescriptionProps> = ({
258
+ className,
259
+ children,
260
+ }) => {
261
+ return (
262
+ <Text className={cn("text-sm text-muted", className)}>
263
+ {children}
264
+ </Text>
265
+ );
266
+ };
267
+ BottomSheetDescription.displayName = "BottomSheetDescription";
268
+
269
+ // --- BottomSheetBody ---
270
+
271
+ export interface BottomSheetBodyProps extends ViewProps {
272
+ className?: string;
273
+ children: React.ReactNode;
274
+ }
275
+
276
+ export const BottomSheetBody = React.forwardRef<View, BottomSheetBodyProps>(
277
+ ({ className, children, ...props }, ref) => (
278
+ <View ref={ref} className={cn("py-2", className)} {...props}>
279
+ {children}
280
+ </View>
281
+ )
282
+ );
283
+ BottomSheetBody.displayName = "BottomSheetBody";
284
+
285
+ // --- BottomSheetFooter ---
286
+
287
+ export interface BottomSheetFooterProps extends ViewProps {
288
+ className?: string;
289
+ children: React.ReactNode;
290
+ }
291
+
292
+ export const BottomSheetFooter = React.forwardRef<View, BottomSheetFooterProps>(
293
+ ({ className, children, ...props }, ref) => (
294
+ <View
295
+ ref={ref}
296
+ className={cn("mt-6 flex-row items-center justify-end gap-3", className)}
297
+ {...props}
298
+ >
299
+ {children}
300
+ </View>
301
+ )
302
+ );
303
+ BottomSheetFooter.displayName = "BottomSheetFooter";
304
+
305
+ // --- BottomSheetClose ---
306
+
307
+ export interface BottomSheetCloseProps extends PressableProps {
308
+ asChild?: boolean;
309
+ className?: string;
310
+ children: React.ReactNode;
311
+ }
312
+
313
+ export const BottomSheetClose = React.forwardRef<View, BottomSheetCloseProps>(
314
+ ({ asChild, children, onPress, ...props }, ref) => {
315
+ const { closeSheet } = useBottomSheetContext();
316
+
317
+ const handlePress = (e: any) => {
318
+ closeSheet();
319
+ onPress?.(e);
320
+ };
321
+
322
+ if (asChild && React.isValidElement(children)) {
323
+ return React.cloneElement(children as React.ReactElement<any>, {
324
+ ref,
325
+ onPress: handlePress,
326
+ });
327
+ }
328
+
329
+ return (
330
+ <Pressable ref={ref} onPress={handlePress} {...props}>
331
+ {children}
332
+ </Pressable>
333
+ );
334
+ }
335
+ );
336
+ BottomSheetClose.displayName = "BottomSheetClose";
@@ -0,0 +1 @@
1
+ export * from "./bottom-sheet";