@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.
- package/dist/index.d.ts +5 -0
- package/dist/index.js +14 -0
- package/package.json +31 -0
- package/src/components/ui/accordion.tsx +334 -0
- package/src/components/ui/avatar.tsx +326 -0
- package/src/components/ui/badge.tsx +84 -0
- package/src/components/ui/banner.tsx +151 -0
- package/src/components/ui/bottom-sheet.tsx +579 -0
- package/src/components/ui/button.tsx +142 -0
- package/src/components/ui/calendar.tsx +502 -0
- package/src/components/ui/card.tsx +163 -0
- package/src/components/ui/checkbox.tsx +129 -0
- package/src/components/ui/date-picker.tsx +190 -0
- package/src/components/ui/date-range-picker.tsx +262 -0
- package/src/components/ui/dialog.tsx +204 -0
- package/src/components/ui/form.tsx +139 -0
- package/src/components/ui/input.tsx +107 -0
- package/src/components/ui/radio-group.tsx +123 -0
- package/src/components/ui/radio.tsx +109 -0
- package/src/components/ui/select-sheet.tsx +814 -0
- package/src/components/ui/select.tsx +547 -0
- package/src/components/ui/tabs.tsx +254 -0
- package/src/components/ui/text.tsx +229 -0
- package/src/components/ui/textarea.tsx +77 -0
- package/src/components/v0/accordion.tsx +199 -0
- package/src/components/v1/accordion.tsx +234 -0
- package/src/components/v1/avatar.tsx +259 -0
- package/src/components/v1/bottom-sheet.tsx +1090 -0
- package/src/components/v1/button.tsx +61 -0
- package/src/components/v1/calendar.tsx +498 -0
- package/src/components/v1/card.tsx +86 -0
- package/src/components/v1/checkbox.tsx +46 -0
- package/src/components/v1/date-picker.tsx +135 -0
- package/src/components/v1/date-range-picker.tsx +218 -0
- package/src/components/v1/dialog.tsx +211 -0
- package/src/components/v1/radio-group.tsx +76 -0
- package/src/components/v1/select.tsx +217 -0
- package/src/components/v1/tabs.tsx +253 -0
- package/src/registry/ui/accordion.json +30 -0
- package/src/registry/ui/avatar.json +41 -0
- package/src/registry/ui/badge.json +26 -0
- package/src/registry/ui/banner.json +27 -0
- package/src/registry/ui/bottom-sheet.json +29 -0
- package/src/registry/ui/button.json +24 -0
- package/src/registry/ui/calendar.json +29 -0
- package/src/registry/ui/card.json +25 -0
- package/src/registry/ui/checkbox.json +25 -0
- package/src/registry/ui/date-picker.json +30 -0
- package/src/registry/ui/date-range-picker.json +33 -0
- package/src/registry/ui/dialog.json +25 -0
- package/src/registry/ui/form.json +27 -0
- package/src/registry/ui/input.json +22 -0
- package/src/registry/ui/radio-group.json +26 -0
- package/src/registry/ui/radio.json +23 -0
- package/src/registry/ui/select-sheet.json +29 -0
- package/src/registry/ui/select.json +26 -0
- package/src/registry/ui/tabs.json +29 -0
- package/src/registry/ui/text.json +22 -0
- 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
|
+
}
|