@gv-tech/ui-native 2.6.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 (55) hide show
  1. package/package.json +80 -0
  2. package/src/accordion.tsx +93 -0
  3. package/src/alert-dialog.tsx +123 -0
  4. package/src/alert.tsx +50 -0
  5. package/src/aspect-ratio.tsx +9 -0
  6. package/src/avatar.tsx +38 -0
  7. package/src/badge.tsx +51 -0
  8. package/src/breadcrumb.tsx +9 -0
  9. package/src/button.tsx +75 -0
  10. package/src/calendar.tsx +9 -0
  11. package/src/card.tsx +56 -0
  12. package/src/carousel.tsx +9 -0
  13. package/src/chart.tsx +9 -0
  14. package/src/checkbox.tsx +31 -0
  15. package/src/collapsible.tsx +15 -0
  16. package/src/command.tsx +9 -0
  17. package/src/context-menu.tsx +9 -0
  18. package/src/dialog.tsx +121 -0
  19. package/src/drawer.tsx +9 -0
  20. package/src/dropdown-menu.tsx +9 -0
  21. package/src/form.tsx +9 -0
  22. package/src/hover-card.tsx +9 -0
  23. package/src/index.ts +209 -0
  24. package/src/input.tsx +27 -0
  25. package/src/label.tsx +29 -0
  26. package/src/lib/render-native.tsx +17 -0
  27. package/src/lib/utils.ts +6 -0
  28. package/src/menubar.tsx +9 -0
  29. package/src/nativewind-env.d.ts +1 -0
  30. package/src/navigation-menu.tsx +9 -0
  31. package/src/pagination.tsx +9 -0
  32. package/src/popover.tsx +9 -0
  33. package/src/progress.tsx +9 -0
  34. package/src/radio-group.tsx +42 -0
  35. package/src/resizable.tsx +25 -0
  36. package/src/scroll-area.tsx +9 -0
  37. package/src/search.tsx +17 -0
  38. package/src/select.tsx +229 -0
  39. package/src/separator.tsx +20 -0
  40. package/src/sheet.tsx +127 -0
  41. package/src/skeleton.tsx +31 -0
  42. package/src/slider.tsx +9 -0
  43. package/src/sonner.tsx +9 -0
  44. package/src/switch.tsx +34 -0
  45. package/src/table.tsx +73 -0
  46. package/src/tabs.tsx +74 -0
  47. package/src/text.tsx +43 -0
  48. package/src/textarea.tsx +29 -0
  49. package/src/theme-provider.tsx +6 -0
  50. package/src/theme-toggle.tsx +11 -0
  51. package/src/toast.tsx +88 -0
  52. package/src/toaster.tsx +9 -0
  53. package/src/toggle-group.tsx +78 -0
  54. package/src/toggle.tsx +35 -0
  55. package/src/tooltip.tsx +44 -0
package/package.json ADDED
@@ -0,0 +1,80 @@
1
+ {
2
+ "name": "@gv-tech/ui-native",
3
+ "version": "2.6.0",
4
+ "description": "React Native implementations of the GV Tech design system components",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "https://github.com/Garcia-Ventures/gvtech-design.git",
8
+ "directory": "packages/ui-native"
9
+ },
10
+ "license": "MIT",
11
+ "author": "Eric N. Garcia <eng618@garciaericn.com>",
12
+ "exports": {
13
+ ".": {
14
+ "types": "./src/index.ts",
15
+ "default": "./src/index.ts"
16
+ },
17
+ "./*": {
18
+ "types": "./src/*/index.ts",
19
+ "default": "./src/*/index.ts"
20
+ }
21
+ },
22
+ "main": "src/index.ts",
23
+ "types": "src/index.ts",
24
+ "files": [
25
+ "src",
26
+ "!src/**/*.test.*",
27
+ "!src/**/*.spec.*"
28
+ ],
29
+ "scripts": {
30
+ "build": "echo 'No build step — consumed as TS source by sibling packages'",
31
+ "lint": "echo 'Linted from workspace root'",
32
+ "test": "vitest run",
33
+ "typecheck": "npx tsc --noEmit"
34
+ },
35
+ "dependencies": {
36
+ "@gv-tech/design-tokens": "2.6.0",
37
+ "@gv-tech/ui-core": "2.6.0",
38
+ "@rn-primitives/accordion": "^1.2.0",
39
+ "@rn-primitives/alert-dialog": "^1.2.0",
40
+ "@rn-primitives/aspect-ratio": "^1.2.0",
41
+ "@rn-primitives/avatar": "^1.2.0",
42
+ "@rn-primitives/checkbox": "^1.2.0",
43
+ "@rn-primitives/collapsible": "^1.2.0",
44
+ "@rn-primitives/context-menu": "^1.2.0",
45
+ "@rn-primitives/dialog": "^1.2.0",
46
+ "@rn-primitives/dropdown-menu": "^1.2.0",
47
+ "@rn-primitives/hover-card": "^1.2.0",
48
+ "@rn-primitives/label": "^1.2.0",
49
+ "@rn-primitives/menubar": "^1.2.0",
50
+ "@rn-primitives/navigation-menu": "^1.2.0",
51
+ "@rn-primitives/popover": "^1.2.0",
52
+ "@rn-primitives/portal": "^1.3.0",
53
+ "@rn-primitives/progress": "^1.2.0",
54
+ "@rn-primitives/radio-group": "^1.2.0",
55
+ "@rn-primitives/select": "^1.2.0",
56
+ "@rn-primitives/separator": "^1.2.0",
57
+ "@rn-primitives/slider": "^1.2.0",
58
+ "@rn-primitives/slot": "^1.2.0",
59
+ "@rn-primitives/switch": "^1.2.0",
60
+ "@rn-primitives/tabs": "^1.2.0",
61
+ "@rn-primitives/toast": "^1.2.0",
62
+ "@rn-primitives/toggle": "^1.2.0",
63
+ "@rn-primitives/toggle-group": "^1.2.0",
64
+ "@rn-primitives/tooltip": "^1.2.0",
65
+ "clsx": "^2.1.1",
66
+ "lucide-react-native": "^0.574.0",
67
+ "nativewind": "^4.2.1",
68
+ "react-native-reanimated": "~3.16.1",
69
+ "react-native-svg": "^15.15.3",
70
+ "tailwind-merge": "^3.4.1",
71
+ "tailwindcss": "^4.1.18"
72
+ },
73
+ "peerDependencies": {
74
+ "react": ">=18",
75
+ "react-native": ">=0.72"
76
+ },
77
+ "publishConfig": {
78
+ "access": "public"
79
+ }
80
+ }
@@ -0,0 +1,93 @@
1
+ import * as AccordionPrimitive from '@rn-primitives/accordion';
2
+ import { ChevronDown } from 'lucide-react-native';
3
+ import * as React from 'react';
4
+ import { View } from 'react-native';
5
+ import Animated, {
6
+ Extrapolation,
7
+ interpolate,
8
+ useAnimatedStyle,
9
+ useDerivedValue,
10
+ withTiming,
11
+ } from 'react-native-reanimated';
12
+
13
+ import { cn } from './lib/utils';
14
+
15
+ const Accordion = React.forwardRef<
16
+ React.ElementRef<typeof AccordionPrimitive.Root>,
17
+ React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Root>
18
+ >(({ className, ...props }, ref) => {
19
+ return <AccordionPrimitive.Root ref={ref} className={cn('web:gap-0', className)} {...props} />;
20
+ });
21
+ Accordion.displayName = AccordionPrimitive.Root?.displayName || 'Accordion';
22
+
23
+ const AccordionItem = React.forwardRef<
24
+ React.ElementRef<typeof AccordionPrimitive.Item>,
25
+ React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Item>
26
+ >(({ className, ...props }, ref) => {
27
+ return (
28
+ <AccordionPrimitive.Item ref={ref} className={cn('border-b border-border overflow-hidden', className)} {...props} />
29
+ );
30
+ });
31
+ AccordionItem.displayName = AccordionPrimitive.Item?.displayName || 'AccordionItem';
32
+
33
+ const AccordionHeader = React.forwardRef<
34
+ React.ElementRef<typeof AccordionPrimitive.Header>,
35
+ React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Header>
36
+ >(({ className, ...props }, ref) => {
37
+ return <AccordionPrimitive.Header ref={ref} className={cn('flex flex-row', className)} {...props} />;
38
+ });
39
+ AccordionHeader.displayName = AccordionPrimitive.Header?.displayName || 'AccordionHeader';
40
+
41
+ const AccordionTrigger = React.forwardRef<
42
+ React.ElementRef<typeof AccordionPrimitive.Trigger>,
43
+ React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Trigger>
44
+ >(({ className, children, ...props }, ref) => {
45
+ const { isExpanded } = AccordionPrimitive.useItemContext();
46
+ const progress = useDerivedValue(() =>
47
+ isExpanded ? withTiming(1, { duration: 250 }) : withTiming(0, { duration: 200 }),
48
+ );
49
+ const chevronStyle = useAnimatedStyle(() => ({
50
+ transform: [{ rotate: `${progress.value * 180}deg` }],
51
+ opacity: interpolate(progress.value, [0, 1], [1, 0.8], Extrapolation.CLAMP),
52
+ }));
53
+
54
+ return (
55
+ <AccordionPrimitive.Header className="flex">
56
+ <AccordionPrimitive.Trigger
57
+ ref={ref}
58
+ className={cn(
59
+ 'flex flex-row items-center justify-between py-4 font-medium transition-all hover:underline [&[data-state=open]>svg]:rotate-180',
60
+ className,
61
+ )}
62
+ {...props}
63
+ >
64
+ <>{children}</>
65
+ <Animated.View style={chevronStyle}>
66
+ <ChevronDown className="h-4 w-4 shrink-0 text-muted-foreground transition-transform duration-200" />
67
+ </Animated.View>
68
+ </AccordionPrimitive.Trigger>
69
+ </AccordionPrimitive.Header>
70
+ );
71
+ });
72
+ AccordionTrigger.displayName = AccordionPrimitive.Trigger?.displayName || 'AccordionTrigger';
73
+
74
+ const AccordionContent = React.forwardRef<
75
+ React.ElementRef<typeof AccordionPrimitive.Content>,
76
+ React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Content>
77
+ >(({ className, children, ...props }, ref) => {
78
+ return (
79
+ <AccordionPrimitive.Content
80
+ ref={ref}
81
+ className={cn(
82
+ 'overflow-hidden text-sm transition-all data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down',
83
+ className,
84
+ )}
85
+ {...props}
86
+ >
87
+ <View className={cn('pb-4 pt-0', className)}>{children}</View>
88
+ </AccordionPrimitive.Content>
89
+ );
90
+ });
91
+ AccordionContent.displayName = AccordionPrimitive.Content?.displayName || 'AccordionContent';
92
+
93
+ export { Accordion, AccordionContent, AccordionItem, AccordionTrigger };
@@ -0,0 +1,123 @@
1
+ import * as AlertDialogPrimitive from '@rn-primitives/alert-dialog';
2
+ import * as React from 'react';
3
+ import { StyleSheet, View, type ViewStyle } from 'react-native';
4
+ import Animated, { FadeIn, FadeOut } from 'react-native-reanimated';
5
+
6
+ import { buttonVariants } from './button';
7
+ import { cn } from './lib/utils';
8
+
9
+ const AlertDialog = AlertDialogPrimitive.Root;
10
+
11
+ const AlertDialogTrigger = AlertDialogPrimitive.Trigger;
12
+
13
+ const AlertDialogPortal = AlertDialogPrimitive.Portal;
14
+
15
+ const AlertDialogOverlay = React.forwardRef<
16
+ React.ElementRef<typeof AlertDialogPrimitive.Overlay>,
17
+ React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Overlay>
18
+ >(({ className, ...props }, ref) => {
19
+ return (
20
+ <AlertDialogPrimitive.Overlay style={StyleSheet.absoluteFill} asChild ref={ref} {...props}>
21
+ <Animated.View
22
+ entering={FadeIn.duration(150)}
23
+ exiting={FadeOut.duration(150)}
24
+ className={cn('z-50 bg-black/80 flex justify-center items-center p-2', className)}
25
+ />
26
+ </AlertDialogPrimitive.Overlay>
27
+ );
28
+ });
29
+ AlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay?.displayName || 'AlertDialogOverlay';
30
+
31
+ const AlertDialogContent = React.forwardRef<
32
+ React.ElementRef<typeof AlertDialogPrimitive.Content>,
33
+ React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Content> & {
34
+ portalHost?: string;
35
+ overlayClassName?: string;
36
+ overlayStyle?: ViewStyle;
37
+ }
38
+ >(({ className, portalHost, overlayClassName, overlayStyle, ...props }, ref) => {
39
+ return (
40
+ <AlertDialogPortal hostName={portalHost}>
41
+ <AlertDialogOverlay className={overlayClassName} style={overlayStyle} />
42
+ <AlertDialogPrimitive.Content ref={ref} asChild {...props}>
43
+ <Animated.View
44
+ entering={FadeIn.duration(150)}
45
+ exiting={FadeOut.duration(150)}
46
+ className={cn(
47
+ 'z-50 max-w-lg gap-4 border border-border bg-background p-6 shadow-lg sm:rounded-lg w-full rounded-xl',
48
+ className,
49
+ )}
50
+ />
51
+ </AlertDialogPrimitive.Content>
52
+ </AlertDialogPortal>
53
+ );
54
+ });
55
+ AlertDialogContent.displayName = AlertDialogPrimitive.Content?.displayName || 'AlertDialogContent';
56
+
57
+ const AlertDialogHeader = ({ className, ...props }: React.ComponentPropsWithoutRef<typeof View>) => (
58
+ <View className={cn('flex flex-col gap-2 text-center sm:text-left', className)} {...props} />
59
+ );
60
+ AlertDialogHeader.displayName = 'AlertDialogHeader';
61
+
62
+ const AlertDialogFooter = ({ className, ...props }: React.ComponentPropsWithoutRef<typeof View>) => (
63
+ <View className={cn('flex flex-col-reverse sm:flex-row sm:justify-end gap-2', className)} {...props} />
64
+ );
65
+ AlertDialogFooter.displayName = 'AlertDialogFooter';
66
+
67
+ const AlertDialogTitle = React.forwardRef<
68
+ React.ElementRef<typeof AlertDialogPrimitive.Title>,
69
+ React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Title>
70
+ >(({ className, ...props }, ref) => (
71
+ <AlertDialogPrimitive.Title
72
+ ref={ref}
73
+ className={cn('text-lg native:text-xl font-semibold text-foreground', className)}
74
+ {...props}
75
+ />
76
+ ));
77
+ AlertDialogTitle.displayName = AlertDialogPrimitive.Title?.displayName || 'AlertDialogTitle';
78
+
79
+ const AlertDialogDescription = React.forwardRef<
80
+ React.ElementRef<typeof AlertDialogPrimitive.Description>,
81
+ React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Description>
82
+ >(({ className, ...props }, ref) => (
83
+ <AlertDialogPrimitive.Description
84
+ ref={ref}
85
+ className={cn('text-sm native:text-base text-muted-foreground', className)}
86
+ {...props}
87
+ />
88
+ ));
89
+ AlertDialogDescription.displayName = AlertDialogPrimitive.Description?.displayName || 'AlertDialogDescription';
90
+
91
+ const AlertDialogAction = React.forwardRef<
92
+ React.ElementRef<typeof AlertDialogPrimitive.Action>,
93
+ React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Action>
94
+ >(({ className, ...props }, ref) => (
95
+ <AlertDialogPrimitive.Action ref={ref} className={cn(buttonVariants(), className)} {...props} />
96
+ ));
97
+ AlertDialogAction.displayName = AlertDialogPrimitive.Action?.displayName || 'AlertDialogAction';
98
+
99
+ const AlertDialogCancel = React.forwardRef<
100
+ React.ElementRef<typeof AlertDialogPrimitive.Cancel>,
101
+ React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Cancel>
102
+ >(({ className, ...props }, ref) => (
103
+ <AlertDialogPrimitive.Cancel
104
+ ref={ref}
105
+ className={cn(buttonVariants({ variant: 'outline' }), 'mt-2 sm:mt-0', className)}
106
+ {...props}
107
+ />
108
+ ));
109
+ AlertDialogCancel.displayName = AlertDialogPrimitive.Cancel?.displayName || 'AlertDialogCancel';
110
+
111
+ export {
112
+ AlertDialog,
113
+ AlertDialogAction,
114
+ AlertDialogCancel,
115
+ AlertDialogContent,
116
+ AlertDialogDescription,
117
+ AlertDialogFooter,
118
+ AlertDialogHeader,
119
+ AlertDialogOverlay,
120
+ AlertDialogPortal,
121
+ AlertDialogTitle,
122
+ AlertDialogTrigger,
123
+ };
package/src/alert.tsx ADDED
@@ -0,0 +1,50 @@
1
+ import { cva, type VariantProps } from 'class-variance-authority';
2
+ import * as React from 'react';
3
+ import { Text, View } from 'react-native';
4
+
5
+ import { wrapTextChildren } from './lib/render-native';
6
+ import { cn } from './lib/utils';
7
+
8
+ const alertVariants = cva('relative w-full rounded-lg border p-4', {
9
+ variants: {
10
+ variant: {
11
+ default: 'bg-background border-border',
12
+ destructive: 'border-destructive/50 bg-destructive/10',
13
+ warning: 'border-amber-500/50 bg-amber-500/10',
14
+ info: 'border-blue-500/50 bg-blue-500/10',
15
+ },
16
+ },
17
+ defaultVariants: {
18
+ variant: 'default',
19
+ },
20
+ });
21
+
22
+ const Alert = React.forwardRef<
23
+ React.ElementRef<typeof View>,
24
+ React.ComponentPropsWithoutRef<typeof View> & VariantProps<typeof alertVariants>
25
+ >(({ className, variant, children, ...props }, ref) => (
26
+ <View ref={ref} className={cn(alertVariants({ variant }), className)} {...props}>
27
+ {wrapTextChildren(children)}
28
+ </View>
29
+ ));
30
+ Alert.displayName = 'Alert';
31
+
32
+ const AlertTitle = React.forwardRef<React.ElementRef<typeof Text>, React.ComponentPropsWithoutRef<typeof Text>>(
33
+ ({ className, ...props }, ref) => (
34
+ <Text
35
+ ref={ref}
36
+ className={cn('mb-1 font-medium leading-none tracking-tight text-foreground', className)}
37
+ {...props}
38
+ />
39
+ ),
40
+ );
41
+ AlertTitle.displayName = 'AlertTitle';
42
+
43
+ const AlertDescription = React.forwardRef<React.ElementRef<typeof Text>, React.ComponentPropsWithoutRef<typeof Text>>(
44
+ ({ className, ...props }, ref) => (
45
+ <Text ref={ref} className={cn('text-sm text-muted-foreground leading-relaxed', className)} {...props} />
46
+ ),
47
+ );
48
+ AlertDescription.displayName = 'AlertDescription';
49
+
50
+ export { Alert, AlertDescription, AlertTitle };
@@ -0,0 +1,9 @@
1
+ import { Text, View } from 'react-native';
2
+
3
+ export const AspectRatio = () => {
4
+ return (
5
+ <View>
6
+ <Text>aspect-ratio is not yet implemented for React Native</Text>
7
+ </View>
8
+ );
9
+ };
package/src/avatar.tsx ADDED
@@ -0,0 +1,38 @@
1
+ import * as AvatarPrimitive from '@rn-primitives/avatar';
2
+ import * as React from 'react';
3
+
4
+ import { cn } from './lib/utils';
5
+
6
+ const Avatar = React.forwardRef<
7
+ React.ElementRef<typeof AvatarPrimitive.Root>,
8
+ React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Root>
9
+ >(({ className, ...props }, ref) => (
10
+ <AvatarPrimitive.Root
11
+ ref={ref}
12
+ className={cn('relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full', className)}
13
+ {...props}
14
+ />
15
+ ));
16
+ Avatar.displayName = AvatarPrimitive.Root?.displayName || 'Avatar';
17
+
18
+ const AvatarImage = React.forwardRef<
19
+ React.ElementRef<typeof AvatarPrimitive.Image>,
20
+ React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Image>
21
+ >(({ className, ...props }, ref) => (
22
+ <AvatarPrimitive.Image ref={ref} className={cn('aspect-square h-full w-full', className)} {...props} />
23
+ ));
24
+ AvatarImage.displayName = AvatarPrimitive.Image?.displayName || 'AvatarImage';
25
+
26
+ const AvatarFallback = React.forwardRef<
27
+ React.ElementRef<typeof AvatarPrimitive.Fallback>,
28
+ React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Fallback>
29
+ >(({ className, ...props }, ref) => (
30
+ <AvatarPrimitive.Fallback
31
+ ref={ref}
32
+ className={cn('flex h-full w-full items-center justify-center rounded-full bg-muted', className)}
33
+ {...props}
34
+ />
35
+ ));
36
+ AvatarFallback.displayName = AvatarPrimitive.Fallback?.displayName || 'AvatarFallback';
37
+
38
+ export { Avatar, AvatarFallback, AvatarImage };
package/src/badge.tsx ADDED
@@ -0,0 +1,51 @@
1
+ import { cva, type VariantProps } from 'class-variance-authority';
2
+ import * as React from 'react';
3
+ import { Text, View } from 'react-native';
4
+
5
+ import { cn } from './lib/utils';
6
+
7
+ const badgeVariants = cva('flex-row items-center rounded-md border px-2 py-0.5', {
8
+ variants: {
9
+ variant: {
10
+ default: 'border-transparent bg-primary',
11
+ secondary: 'border-transparent bg-secondary',
12
+ destructive: 'border-transparent bg-destructive',
13
+ outline: 'border-border bg-transparent',
14
+ },
15
+ },
16
+ defaultVariants: {
17
+ variant: 'default',
18
+ },
19
+ });
20
+
21
+ const badgeTextVariants = cva('text-xs font-semibold', {
22
+ variants: {
23
+ variant: {
24
+ default: 'text-primary-foreground',
25
+ secondary: 'text-secondary-foreground',
26
+ destructive: 'text-destructive-foreground',
27
+ outline: 'text-foreground',
28
+ },
29
+ },
30
+ defaultVariants: {
31
+ variant: 'default',
32
+ },
33
+ });
34
+
35
+ export interface BadgeProps extends React.ComponentPropsWithoutRef<typeof View>, VariantProps<typeof badgeVariants> {
36
+ textClassName?: string;
37
+ }
38
+
39
+ import { wrapTextChildren } from './lib/render-native';
40
+
41
+ function Badge({ className, textClassName, variant, children, ...props }: BadgeProps) {
42
+ return (
43
+ <View className={cn(badgeVariants({ variant }), className)} {...props}>
44
+ {wrapTextChildren(children, Text, {
45
+ className: cn(badgeTextVariants({ variant }), textClassName),
46
+ })}
47
+ </View>
48
+ );
49
+ }
50
+
51
+ export { Badge, badgeVariants };
@@ -0,0 +1,9 @@
1
+ import { Text, View } from 'react-native';
2
+
3
+ export const Breadcrumb = () => {
4
+ return (
5
+ <View>
6
+ <Text>breadcrumb is not yet implemented for React Native</Text>
7
+ </View>
8
+ );
9
+ };
package/src/button.tsx ADDED
@@ -0,0 +1,75 @@
1
+ import { cva, type VariantProps } from 'class-variance-authority';
2
+ import * as React from 'react';
3
+ import { Pressable, Text, View } from 'react-native';
4
+
5
+ import type { ButtonBaseProps } from '@gv-tech/ui-core';
6
+ import { wrapTextChildren } from './lib/render-native';
7
+ import { cn } from './lib/utils';
8
+
9
+ const buttonVariants = cva(
10
+ 'flex-row items-center justify-center gap-2 rounded-md transition-colors active:opacity-80',
11
+ {
12
+ variants: {
13
+ variant: {
14
+ default: 'bg-primary shadow-sm',
15
+ destructive: 'bg-destructive shadow-sm',
16
+ outline: 'border border-input bg-transparent shadow-sm',
17
+ secondary: 'bg-secondary shadow-sm',
18
+ ghost: 'bg-transparent',
19
+ link: 'bg-transparent',
20
+ },
21
+ size: {
22
+ default: 'h-10 px-4 py-2',
23
+ sm: 'h-9 px-3',
24
+ lg: 'h-12 px-8',
25
+ icon: 'h-10 w-10',
26
+ },
27
+ },
28
+ defaultVariants: {
29
+ variant: 'default',
30
+ size: 'default',
31
+ },
32
+ },
33
+ );
34
+
35
+ const buttonTextVariants = cva('text-sm font-medium', {
36
+ variants: {
37
+ variant: {
38
+ default: 'text-primary-foreground',
39
+ destructive: 'text-destructive-foreground',
40
+ outline: 'text-foreground',
41
+ secondary: 'text-secondary-foreground',
42
+ ghost: 'text-foreground',
43
+ link: 'text-primary underline',
44
+ },
45
+ },
46
+ defaultVariants: {
47
+ variant: 'default',
48
+ },
49
+ });
50
+
51
+ export interface ButtonProps extends VariantProps<typeof buttonVariants>, ButtonBaseProps {
52
+ onPress?: () => void;
53
+ }
54
+
55
+ const Button = React.forwardRef<View, ButtonProps>(
56
+ ({ className, variant, size, onPress, children, disabled, ...props }, ref) => {
57
+ return (
58
+ <Pressable
59
+ ref={ref}
60
+ onPress={onPress}
61
+ disabled={disabled}
62
+ className={cn(buttonVariants({ variant, size, className }), disabled && 'opacity-50')}
63
+ {...props}
64
+ >
65
+ {wrapTextChildren(children, Text, {
66
+ className: cn(buttonTextVariants({ variant })),
67
+ })}
68
+ </Pressable>
69
+ );
70
+ },
71
+ );
72
+
73
+ Button.displayName = 'Button';
74
+
75
+ export { Button, buttonVariants };
@@ -0,0 +1,9 @@
1
+ import { Text, View } from 'react-native';
2
+
3
+ export const Calendar = () => {
4
+ return (
5
+ <View>
6
+ <Text>calendar is not yet implemented for React Native</Text>
7
+ </View>
8
+ );
9
+ };
package/src/card.tsx ADDED
@@ -0,0 +1,56 @@
1
+ import * as React from 'react';
2
+ import { Text, View } from 'react-native';
3
+
4
+ import type { CardBaseProps } from '@gv-tech/ui-core';
5
+ import { wrapTextChildren } from './lib/render-native';
6
+ import { cn } from './lib/utils';
7
+
8
+ export interface CardProps extends React.ComponentPropsWithoutRef<typeof View>, CardBaseProps {}
9
+
10
+ const Card = React.forwardRef<React.ElementRef<typeof View>, CardProps>(({ className, ...props }, ref) => (
11
+ <View ref={ref} className={cn('rounded-xl border border-border bg-card shadow-sm', className)} {...props} />
12
+ ));
13
+ Card.displayName = 'Card';
14
+
15
+ const CardHeader = React.forwardRef<React.ElementRef<typeof View>, React.ComponentPropsWithoutRef<typeof View>>(
16
+ ({ className, ...props }, ref) => (
17
+ <View ref={ref} className={cn('flex flex-col space-y-1.5 p-6', className)} {...props} />
18
+ ),
19
+ );
20
+ CardHeader.displayName = 'CardHeader';
21
+
22
+ const CardTitle = React.forwardRef<React.ElementRef<typeof Text>, React.ComponentPropsWithoutRef<typeof Text>>(
23
+ ({ className, ...props }, ref) => (
24
+ <Text
25
+ ref={ref}
26
+ className={cn('font-semibold leading-none tracking-tight text-card-foreground text-lg', className)}
27
+ {...props}
28
+ />
29
+ ),
30
+ );
31
+ CardTitle.displayName = 'CardTitle';
32
+
33
+ const CardDescription = React.forwardRef<React.ElementRef<typeof Text>, React.ComponentPropsWithoutRef<typeof Text>>(
34
+ ({ className, ...props }, ref) => (
35
+ <Text ref={ref} className={cn('text-sm text-muted-foreground', className)} {...props} />
36
+ ),
37
+ );
38
+ CardDescription.displayName = 'CardDescription';
39
+
40
+ const CardContent = React.forwardRef<React.ElementRef<typeof View>, React.ComponentPropsWithoutRef<typeof View>>(
41
+ ({ className, ...props }, ref) => (
42
+ <View ref={ref} className={cn('p-6 pt-0', className)} {...props}>
43
+ {wrapTextChildren(props.children, Text, { className: 'text-sm text-card-foreground' })}
44
+ </View>
45
+ ),
46
+ );
47
+ CardContent.displayName = 'CardContent';
48
+
49
+ const CardFooter = React.forwardRef<React.ElementRef<typeof View>, React.ComponentPropsWithoutRef<typeof View>>(
50
+ ({ className, ...props }, ref) => (
51
+ <View ref={ref} className={cn('flex flex-row items-center p-6 pt-0', className)} {...props} />
52
+ ),
53
+ );
54
+ CardFooter.displayName = 'CardFooter';
55
+
56
+ export { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle };
@@ -0,0 +1,9 @@
1
+ import { Text, View } from 'react-native';
2
+
3
+ export const Carousel = () => {
4
+ return (
5
+ <View>
6
+ <Text>carousel is not yet implemented for React Native</Text>
7
+ </View>
8
+ );
9
+ };
package/src/chart.tsx ADDED
@@ -0,0 +1,9 @@
1
+ import { Text, View } from 'react-native';
2
+
3
+ export const Chart = () => {
4
+ return (
5
+ <View>
6
+ <Text>chart is not yet implemented for React Native</Text>
7
+ </View>
8
+ );
9
+ };
@@ -0,0 +1,31 @@
1
+ import * as CheckboxPrimitive from '@rn-primitives/checkbox';
2
+ import { Check } from 'lucide-react-native';
3
+ import * as React from 'react';
4
+ import { Platform } from 'react-native';
5
+
6
+ import { cn } from './lib/utils';
7
+
8
+ const Checkbox = React.forwardRef<
9
+ React.ElementRef<typeof CheckboxPrimitive.Root>,
10
+ React.ComponentPropsWithoutRef<typeof CheckboxPrimitive.Root>
11
+ >(({ className, ...props }, ref) => {
12
+ return (
13
+ <CheckboxPrimitive.Root
14
+ ref={ref}
15
+ className={cn(
16
+ 'web:peer h-4 w-4 native:h-[20] native:w-[20] shrink-0 rounded-sm native:rounded border border-primary web:ring-offset-background web:focus-visible:outline-none web:focus-visible:ring-2 web:focus-visible:ring-ring web:focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50',
17
+ props.checked && 'bg-primary',
18
+ className,
19
+ )}
20
+ {...props}
21
+ >
22
+ <CheckboxPrimitive.Indicator className={cn('items-center justify-center h-full w-full')}>
23
+ <Check size={12} strokeWidth={Platform.OS === 'web' ? 2.5 : 3.5} className="text-primary-foreground" />
24
+ </CheckboxPrimitive.Indicator>
25
+ </CheckboxPrimitive.Root>
26
+ );
27
+ });
28
+ Checkbox.displayName = CheckboxPrimitive.Root?.displayName || 'Checkbox';
29
+
30
+ export { Checkbox };
31
+ export type CheckboxProps = React.ComponentPropsWithoutRef<typeof CheckboxPrimitive.Root>;
@@ -0,0 +1,15 @@
1
+ import { CollapsibleBaseProps, CollapsibleContentBaseProps, CollapsibleTriggerBaseProps } from '@gv-tech/ui-core';
2
+ import * as CollapsiblePrimitive from '@rn-primitives/collapsible';
3
+
4
+ const Collapsible = CollapsiblePrimitive.Root;
5
+
6
+ const CollapsibleTrigger = CollapsiblePrimitive.Trigger;
7
+
8
+ const CollapsibleContent = CollapsiblePrimitive.Content;
9
+
10
+ export { Collapsible, CollapsibleContent, CollapsibleTrigger };
11
+ export type {
12
+ CollapsibleContentBaseProps as CollapsibleContentProps,
13
+ CollapsibleBaseProps as CollapsibleProps,
14
+ CollapsibleTriggerBaseProps as CollapsibleTriggerProps,
15
+ };