@lunar-kit/core 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/dist/index.d.ts +5 -0
  2. package/dist/index.js +14 -0
  3. package/package.json +31 -0
  4. package/src/components/ui/accordion.tsx +334 -0
  5. package/src/components/ui/avatar.tsx +326 -0
  6. package/src/components/ui/badge.tsx +84 -0
  7. package/src/components/ui/banner.tsx +151 -0
  8. package/src/components/ui/bottom-sheet.tsx +579 -0
  9. package/src/components/ui/button.tsx +142 -0
  10. package/src/components/ui/calendar.tsx +502 -0
  11. package/src/components/ui/card.tsx +163 -0
  12. package/src/components/ui/checkbox.tsx +129 -0
  13. package/src/components/ui/date-picker.tsx +190 -0
  14. package/src/components/ui/date-range-picker.tsx +262 -0
  15. package/src/components/ui/dialog.tsx +204 -0
  16. package/src/components/ui/form.tsx +139 -0
  17. package/src/components/ui/input.tsx +107 -0
  18. package/src/components/ui/radio-group.tsx +123 -0
  19. package/src/components/ui/radio.tsx +109 -0
  20. package/src/components/ui/select-sheet.tsx +814 -0
  21. package/src/components/ui/select.tsx +547 -0
  22. package/src/components/ui/tabs.tsx +254 -0
  23. package/src/components/ui/text.tsx +229 -0
  24. package/src/components/ui/textarea.tsx +77 -0
  25. package/src/components/v0/accordion.tsx +199 -0
  26. package/src/components/v1/accordion.tsx +234 -0
  27. package/src/components/v1/avatar.tsx +259 -0
  28. package/src/components/v1/bottom-sheet.tsx +1090 -0
  29. package/src/components/v1/button.tsx +61 -0
  30. package/src/components/v1/calendar.tsx +498 -0
  31. package/src/components/v1/card.tsx +86 -0
  32. package/src/components/v1/checkbox.tsx +46 -0
  33. package/src/components/v1/date-picker.tsx +135 -0
  34. package/src/components/v1/date-range-picker.tsx +218 -0
  35. package/src/components/v1/dialog.tsx +211 -0
  36. package/src/components/v1/radio-group.tsx +76 -0
  37. package/src/components/v1/select.tsx +217 -0
  38. package/src/components/v1/tabs.tsx +253 -0
  39. package/src/registry/ui/accordion.json +30 -0
  40. package/src/registry/ui/avatar.json +41 -0
  41. package/src/registry/ui/badge.json +26 -0
  42. package/src/registry/ui/banner.json +27 -0
  43. package/src/registry/ui/bottom-sheet.json +29 -0
  44. package/src/registry/ui/button.json +24 -0
  45. package/src/registry/ui/calendar.json +29 -0
  46. package/src/registry/ui/card.json +25 -0
  47. package/src/registry/ui/checkbox.json +25 -0
  48. package/src/registry/ui/date-picker.json +30 -0
  49. package/src/registry/ui/date-range-picker.json +33 -0
  50. package/src/registry/ui/dialog.json +25 -0
  51. package/src/registry/ui/form.json +27 -0
  52. package/src/registry/ui/input.json +22 -0
  53. package/src/registry/ui/radio-group.json +26 -0
  54. package/src/registry/ui/radio.json +23 -0
  55. package/src/registry/ui/select-sheet.json +29 -0
  56. package/src/registry/ui/select.json +26 -0
  57. package/src/registry/ui/tabs.json +29 -0
  58. package/src/registry/ui/text.json +22 -0
  59. package/src/registry/ui/textarea.json +24 -0
@@ -0,0 +1,84 @@
1
+ // components/ui/badge.tsx
2
+ import * as React from 'react';
3
+ import { View, type ViewProps } from 'react-native';
4
+ import { cva, type VariantProps } from 'class-variance-authority';
5
+ import { cn } from '@/lib/utils';
6
+ import { Text } from './text';
7
+
8
+ const badgeVariants = cva(
9
+ 'flex-row items-center justify-center rounded-full',
10
+ {
11
+ variants: {
12
+ variant: {
13
+ default: 'bg-primary',
14
+ secondary: 'bg-secondary',
15
+ success: 'bg-green-500',
16
+ warning: 'bg-yellow-500',
17
+ destructive: 'bg-destructive',
18
+ outline: 'border border-input bg-transparent',
19
+ muted: 'bg-muted',
20
+ },
21
+ size: {
22
+ sm: 'px-2 py-0.5',
23
+ md: 'px-2.5 py-1',
24
+ lg: 'px-3 py-1.5',
25
+ },
26
+ },
27
+ defaultVariants: {
28
+ variant: 'default',
29
+ size: 'md',
30
+ },
31
+ }
32
+ );
33
+
34
+ const badgeTextVariants = cva('font-medium', {
35
+ variants: {
36
+ variant: {
37
+ default: 'text-primary-foreground',
38
+ secondary: 'text-secondary-foreground',
39
+ success: 'text-white',
40
+ warning: 'text-white',
41
+ destructive: 'text-destructive-foreground',
42
+ outline: 'text-foreground',
43
+ muted: 'text-muted-foreground',
44
+ },
45
+ size: {
46
+ sm: 'text-xs',
47
+ md: 'text-sm',
48
+ lg: 'text-base',
49
+ },
50
+ },
51
+ defaultVariants: {
52
+ variant: 'default',
53
+ size: 'md',
54
+ },
55
+ });
56
+
57
+ export interface BadgeProps
58
+ extends ViewProps,
59
+ VariantProps<typeof badgeVariants> {
60
+ children: string;
61
+ textClassName?: string;
62
+ }
63
+
64
+ export function Badge({
65
+ className,
66
+ textClassName,
67
+ variant,
68
+ size,
69
+ children,
70
+ ...props
71
+ }: BadgeProps) {
72
+ return (
73
+ <View
74
+ className={cn(badgeVariants({ variant, size }), className)}
75
+ {...props}
76
+ >
77
+ <Text
78
+ className={cn(badgeTextVariants({ variant, size }), textClassName)}
79
+ >
80
+ {children}
81
+ </Text>
82
+ </View>
83
+ );
84
+ }
@@ -0,0 +1,151 @@
1
+ // components/ui/banner.tsx
2
+ import * as React from 'react';
3
+ import { View, Pressable, type ViewProps } from 'react-native';
4
+ import { cva, type VariantProps } from 'class-variance-authority';
5
+ import { cn } from '@/lib/utils';
6
+ import { Text } from './text';
7
+ import { X, Info, AlertCircle, CheckCircle, AlertTriangle } from 'lucide-react-native';
8
+ import { useThemeColors } from '@/hooks/useThemeColors';
9
+
10
+ const bannerVariants = cva(
11
+ 'flex-row items-start p-4 rounded-lg border',
12
+ {
13
+ variants: {
14
+ variant: {
15
+ default: 'bg-muted border-border',
16
+ info: 'bg-blue-50 border-blue-200 dark:bg-blue-950/30 dark:border-blue-900',
17
+ success: 'bg-green-50 border-green-200 dark:bg-green-950/30 dark:border-green-900',
18
+ warning: 'bg-yellow-50 border-yellow-200 dark:bg-yellow-950/30 dark:border-yellow-900',
19
+ destructive: 'bg-red-50 border-red-200 dark:bg-red-950/30 dark:border-red-900',
20
+ },
21
+ },
22
+ defaultVariants: {
23
+ variant: 'default',
24
+ },
25
+ }
26
+ );
27
+
28
+ type BannerVariant = 'default' | 'info' | 'success' | 'warning' | 'destructive';
29
+
30
+ const iconColorMap: Record<BannerVariant, string> = {
31
+ default: 'mutedForeground',
32
+ info: '#3b82f6',
33
+ success: '#22c55e',
34
+ warning: '#eab308',
35
+ destructive: '#ef4444',
36
+ };
37
+
38
+ const textColorMap: Record<BannerVariant, string> = {
39
+ default: 'text-foreground',
40
+ info: 'text-blue-900 dark:text-blue-100',
41
+ success: 'text-green-900 dark:text-green-100',
42
+ warning: 'text-yellow-900 dark:text-yellow-100',
43
+ destructive: 'text-red-900 dark:text-red-100',
44
+ };
45
+
46
+ export interface BannerProps
47
+ extends ViewProps,
48
+ VariantProps<typeof bannerVariants> {
49
+ title?: string;
50
+ description?: string;
51
+ children?: React.ReactNode;
52
+ icon?: React.ReactNode;
53
+ showIcon?: boolean;
54
+ dismissible?: boolean;
55
+ onDismiss?: () => void;
56
+ }
57
+
58
+ export function Banner({
59
+ className,
60
+ variant = 'default',
61
+ title,
62
+ description,
63
+ children,
64
+ icon,
65
+ showIcon = true,
66
+ dismissible = false,
67
+ onDismiss,
68
+ ...props
69
+ }: BannerProps) {
70
+ const { colors } = useThemeColors();
71
+ const [dismissed, setDismissed] = React.useState(false);
72
+
73
+ const handleDismiss = () => {
74
+ setDismissed(true);
75
+ onDismiss?.();
76
+ };
77
+
78
+ if (dismissed) return null;
79
+
80
+ const currentVariant: BannerVariant = variant || 'default';
81
+
82
+ const getDefaultIcon = () => {
83
+ const iconColor =
84
+ currentVariant === 'default'
85
+ ? colors.mutedForeground
86
+ : iconColorMap[currentVariant];
87
+
88
+ switch (currentVariant) {
89
+ case 'info':
90
+ return <Info size={20} color={iconColor} />;
91
+ case 'success':
92
+ return <CheckCircle size={20} color={iconColor} />;
93
+ case 'warning':
94
+ return <AlertTriangle size={20} color={iconColor} />;
95
+ case 'destructive':
96
+ return <AlertCircle size={20} color={iconColor} />;
97
+ default:
98
+ return <Info size={20} color={iconColor} />;
99
+ }
100
+ };
101
+
102
+ const textColor = textColorMap[currentVariant];
103
+
104
+ return (
105
+ <View
106
+ className={cn(bannerVariants({ variant }), className)}
107
+ {...props}
108
+ >
109
+ {showIcon && (
110
+ <View className="mr-3 mt-0.5">
111
+ {icon || getDefaultIcon()}
112
+ </View>
113
+ )}
114
+
115
+ <View className="flex-1">
116
+ {title && (
117
+ <Text
118
+ size="sm"
119
+ variant='label'
120
+ className={cn('mb-1', textColor)}
121
+ >
122
+ {title}
123
+ </Text>
124
+ )}
125
+ {description && (
126
+ <Text size="sm" className={cn(textColor)}>
127
+ {description}
128
+ </Text>
129
+ )}
130
+ {children}
131
+ </View>
132
+
133
+ {dismissible && (
134
+ <Pressable
135
+ onPress={handleDismiss}
136
+ className="ml-2 p-1"
137
+ hitSlop={{ top: 8, bottom: 8, left: 8, right: 8 }}
138
+ >
139
+ <X
140
+ size={16}
141
+ color={
142
+ currentVariant === 'default'
143
+ ? colors.mutedForeground
144
+ : iconColorMap[currentVariant]
145
+ }
146
+ />
147
+ </Pressable>
148
+ )}
149
+ </View>
150
+ );
151
+ }