@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.
- package/dist/{chunk-2B6HTSGM.mjs → chunk-RNHEGFYR.mjs} +16 -2
- package/dist/chunk-RNHEGFYR.mjs.map +1 -0
- package/dist/index.d.mts +2 -145
- package/dist/index.d.ts +2 -145
- package/dist/index.js +37 -8
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +23 -8
- package/dist/index.mjs.map +1 -1
- package/dist/preset-BmUHLoAa.d.mts +274 -0
- package/dist/preset-BmUHLoAa.d.ts +274 -0
- package/dist/preset.d.mts +1 -117
- package/dist/preset.d.ts +1 -117
- package/dist/preset.js +19 -3
- package/dist/preset.js.map +1 -1
- package/dist/preset.mjs +5 -3
- package/package.json +11 -5
- package/src/components/accordion/accordion.tsx +245 -0
- package/src/components/accordion/index.ts +1 -0
- package/src/components/alert/alert.tsx +118 -0
- package/src/components/alert/index.ts +1 -0
- package/src/components/avatar/avatar.tsx +125 -0
- package/src/components/avatar/index.ts +1 -0
- package/src/components/badge/badge.tsx +89 -0
- package/src/components/badge/index.ts +1 -0
- package/src/components/bottom-sheet/bottom-sheet.tsx +336 -0
- package/src/components/bottom-sheet/index.ts +1 -0
- package/src/components/button/button.tsx +172 -0
- package/src/components/button/index.ts +1 -0
- package/src/components/card/card.tsx +121 -0
- package/src/components/card/index.ts +1 -0
- package/src/components/checkbox/checkbox.tsx +100 -0
- package/src/components/checkbox/index.ts +1 -0
- package/src/components/data-table/data-table.tsx +277 -0
- package/src/components/data-table/index.ts +1 -0
- package/src/components/dialog/dialog.tsx +278 -0
- package/src/components/dialog/index.ts +1 -0
- package/src/components/input/index.ts +1 -0
- package/src/components/input/input.tsx +130 -0
- package/src/components/radio/index.ts +1 -0
- package/src/components/radio/radio.tsx +117 -0
- package/src/components/select/index.ts +1 -0
- package/src/components/select/select.tsx +375 -0
- package/src/components/separator/index.ts +1 -0
- package/src/components/separator/separator.tsx +28 -0
- package/src/components/skeleton/index.ts +1 -0
- package/src/components/skeleton/skeleton.tsx +43 -0
- package/src/components/spinner/index.ts +1 -0
- package/src/components/spinner/spinner.tsx +46 -0
- package/src/components/stats-card/index.ts +1 -0
- package/src/components/stats-card/stats-card.tsx +92 -0
- package/src/components/switch/index.ts +1 -0
- package/src/components/switch/switch.tsx +80 -0
- package/src/components/tabs/index.ts +1 -0
- package/src/components/tabs/tabs.tsx +172 -0
- package/src/components/text/heading.tsx +50 -0
- package/src/components/text/index.ts +2 -0
- package/src/components/text/text.tsx +62 -0
- package/src/components/textarea/index.ts +1 -0
- package/src/components/textarea/textarea.tsx +87 -0
- package/src/components/toast/index.ts +2 -0
- package/src/components/toast/toast.tsx +136 -0
- package/src/components/toast/types.ts +32 -0
- package/src/index.ts +42 -0
- package/src/primitives/box.tsx +25 -0
- package/src/primitives/index.ts +2 -0
- package/src/primitives/pressable.tsx +49 -0
- package/src/providers/BeyondUIProvider.tsx +100 -0
- package/src/templates/auth/ForgotPasswordTemplate.tsx +132 -0
- package/src/templates/auth/SignInTemplate.tsx +213 -0
- package/src/templates/auth/SignUpTemplate.tsx +233 -0
- package/src/templates/auth/index.ts +3 -0
- package/src/templates/dashboard/DashboardTemplate.tsx +205 -0
- package/src/templates/dashboard/index.ts +1 -0
- package/src/templates/index.ts +3 -0
- package/src/templates/settings/SettingsTemplate.tsx +226 -0
- package/src/templates/settings/index.ts +1 -0
- package/src/theme/preset.ts +45 -0
- package/src/theme/tokens.ts +144 -0
- package/src/types/nativewind-env.d.ts +26 -0
- package/src/utilities/accessibility.ts +43 -0
- package/src/utilities/cn.ts +9 -0
- package/src/utilities/index.ts +2 -0
- package/dist/chunk-2B6HTSGM.mjs.map +0 -1
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import {
|
|
3
|
+
View,
|
|
4
|
+
ScrollView,
|
|
5
|
+
Pressable,
|
|
6
|
+
type ViewProps,
|
|
7
|
+
} from "react-native";
|
|
8
|
+
import { cn } from "../../utilities/cn";
|
|
9
|
+
import { Text } from "../../components/text/text";
|
|
10
|
+
import { Heading } from "../../components/text/heading";
|
|
11
|
+
import { Avatar, AvatarFallback, AvatarImage } from "../../components/avatar/avatar";
|
|
12
|
+
import { Badge } from "../../components/badge/badge";
|
|
13
|
+
import { Card, CardHeader, CardTitle, CardContent } from "../../components/card/card";
|
|
14
|
+
import { StatsCard, type StatsCardProps } from "../../components/stats-card/stats-card";
|
|
15
|
+
import { Button } from "../../components/button/button";
|
|
16
|
+
|
|
17
|
+
export interface DashboardMetric extends StatsCardProps {
|
|
18
|
+
id: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface DashboardActivity {
|
|
22
|
+
id: string;
|
|
23
|
+
title: string;
|
|
24
|
+
subtitle: string;
|
|
25
|
+
timestamp: string;
|
|
26
|
+
amount?: string;
|
|
27
|
+
status?: {
|
|
28
|
+
label: string;
|
|
29
|
+
variant: "primary" | "secondary" | "success" | "warning" | "danger" | "outline";
|
|
30
|
+
};
|
|
31
|
+
avatarUrl?: string;
|
|
32
|
+
avatarInitials?: string;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface DashboardQuickAction {
|
|
36
|
+
id: string;
|
|
37
|
+
label: string;
|
|
38
|
+
icon?: string;
|
|
39
|
+
onPress: () => void;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface DashboardTemplateProps extends ViewProps {
|
|
43
|
+
userName: string;
|
|
44
|
+
userRole?: string;
|
|
45
|
+
userAvatarUrl?: string;
|
|
46
|
+
metrics: DashboardMetric[];
|
|
47
|
+
quickActions?: DashboardQuickAction[];
|
|
48
|
+
recentActivities?: DashboardActivity[];
|
|
49
|
+
onViewAllActivities?: () => void;
|
|
50
|
+
onNotificationPress?: () => void;
|
|
51
|
+
unreadNotificationsCount?: number;
|
|
52
|
+
className?: string;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export const DashboardTemplate: React.FC<DashboardTemplateProps> = ({
|
|
56
|
+
userName,
|
|
57
|
+
userRole = "Administrator",
|
|
58
|
+
userAvatarUrl,
|
|
59
|
+
metrics,
|
|
60
|
+
quickActions,
|
|
61
|
+
recentActivities,
|
|
62
|
+
onViewAllActivities,
|
|
63
|
+
onNotificationPress,
|
|
64
|
+
unreadNotificationsCount = 0,
|
|
65
|
+
className,
|
|
66
|
+
...props
|
|
67
|
+
}) => {
|
|
68
|
+
return (
|
|
69
|
+
<ScrollView
|
|
70
|
+
{...props}
|
|
71
|
+
style={[{ flex: 1 }, (props as any).style]}
|
|
72
|
+
className={cn("flex-1 bg-background", className)}
|
|
73
|
+
contentContainerStyle={{ paddingBottom: 40 }}
|
|
74
|
+
showsVerticalScrollIndicator={false}
|
|
75
|
+
>
|
|
76
|
+
{/* Top Greeting Header */}
|
|
77
|
+
<View className="px-6 pt-6 pb-4 flex-row items-center justify-between border-b border-border/40">
|
|
78
|
+
<View className="flex-row items-center gap-3">
|
|
79
|
+
<Avatar size="lg">
|
|
80
|
+
{userAvatarUrl && <AvatarImage source={{ uri: userAvatarUrl }} />}
|
|
81
|
+
<AvatarFallback text={userName.slice(0, 2).toUpperCase()} />
|
|
82
|
+
</Avatar>
|
|
83
|
+
<View>
|
|
84
|
+
<Text className="text-xs text-muted font-medium uppercase tracking-wider">
|
|
85
|
+
{userRole}
|
|
86
|
+
</Text>
|
|
87
|
+
<Heading level={3} className="text-xl font-bold text-foreground">
|
|
88
|
+
Hello, {userName} 👋
|
|
89
|
+
</Heading>
|
|
90
|
+
</View>
|
|
91
|
+
</View>
|
|
92
|
+
|
|
93
|
+
{onNotificationPress && (
|
|
94
|
+
<Pressable
|
|
95
|
+
onPress={onNotificationPress}
|
|
96
|
+
className="w-10 h-10 rounded-full border border-border bg-card items-center justify-center relative active:opacity-70"
|
|
97
|
+
>
|
|
98
|
+
<Text className="text-base text-foreground">🔔</Text>
|
|
99
|
+
{unreadNotificationsCount > 0 && (
|
|
100
|
+
<View className="absolute -top-1 -right-1 w-5 h-5 rounded-full bg-danger items-center justify-center">
|
|
101
|
+
<Text className="text-[10px] font-bold text-white">
|
|
102
|
+
{unreadNotificationsCount > 9 ? "9+" : unreadNotificationsCount}
|
|
103
|
+
</Text>
|
|
104
|
+
</View>
|
|
105
|
+
)}
|
|
106
|
+
</Pressable>
|
|
107
|
+
)}
|
|
108
|
+
</View>
|
|
109
|
+
|
|
110
|
+
<View className="px-6 pt-6 gap-6">
|
|
111
|
+
{/* Quick Actions */}
|
|
112
|
+
{quickActions && quickActions.length > 0 && (
|
|
113
|
+
<View className="gap-2">
|
|
114
|
+
<Text className="text-xs font-bold text-muted uppercase tracking-wider">
|
|
115
|
+
Quick Actions
|
|
116
|
+
</Text>
|
|
117
|
+
<ScrollView
|
|
118
|
+
horizontal
|
|
119
|
+
showsHorizontalScrollIndicator={false}
|
|
120
|
+
className="-mx-6 px-6"
|
|
121
|
+
>
|
|
122
|
+
<View className="flex-row gap-3">
|
|
123
|
+
{quickActions.map((action) => (
|
|
124
|
+
<Button
|
|
125
|
+
key={action.id}
|
|
126
|
+
variant="outline"
|
|
127
|
+
size="sm"
|
|
128
|
+
onPress={action.onPress}
|
|
129
|
+
className="bg-card shadow-sm"
|
|
130
|
+
>
|
|
131
|
+
{action.icon ? `${action.icon} ${action.label}` : action.label}
|
|
132
|
+
</Button>
|
|
133
|
+
))}
|
|
134
|
+
</View>
|
|
135
|
+
</ScrollView>
|
|
136
|
+
</View>
|
|
137
|
+
)}
|
|
138
|
+
|
|
139
|
+
{/* Metrics Grid */}
|
|
140
|
+
<View className="gap-3">
|
|
141
|
+
<Text className="text-xs font-bold text-muted uppercase tracking-wider">
|
|
142
|
+
Overview Performance
|
|
143
|
+
</Text>
|
|
144
|
+
<View className="gap-3">
|
|
145
|
+
{metrics.map((metric) => (
|
|
146
|
+
<StatsCard key={metric.id} {...metric} />
|
|
147
|
+
))}
|
|
148
|
+
</View>
|
|
149
|
+
</View>
|
|
150
|
+
|
|
151
|
+
{/* Recent Activities */}
|
|
152
|
+
{recentActivities && recentActivities.length > 0 && (
|
|
153
|
+
<Card className="gap-2">
|
|
154
|
+
<CardHeader className="flex-row items-center justify-between pb-2">
|
|
155
|
+
<CardTitle className="text-base font-bold">Recent Activity</CardTitle>
|
|
156
|
+
{onViewAllActivities && (
|
|
157
|
+
<Pressable onPress={onViewAllActivities}>
|
|
158
|
+
<Text className="text-xs font-semibold text-primary">View all</Text>
|
|
159
|
+
</Pressable>
|
|
160
|
+
)}
|
|
161
|
+
</CardHeader>
|
|
162
|
+
<CardContent className="gap-3 pt-0">
|
|
163
|
+
{recentActivities.map((act) => (
|
|
164
|
+
<View
|
|
165
|
+
key={act.id}
|
|
166
|
+
className="flex-row items-center justify-between py-2 border-b border-border/40 last:border-b-0"
|
|
167
|
+
>
|
|
168
|
+
<View className="flex-row items-center gap-3 flex-1 pr-2">
|
|
169
|
+
<Avatar size="sm">
|
|
170
|
+
{act.avatarUrl && <AvatarImage source={{ uri: act.avatarUrl }} />}
|
|
171
|
+
<AvatarFallback
|
|
172
|
+
text={act.avatarInitials || act.title.slice(0, 2).toUpperCase()}
|
|
173
|
+
/>
|
|
174
|
+
</Avatar>
|
|
175
|
+
<View className="flex-1">
|
|
176
|
+
<Text className="text-sm font-semibold text-foreground" numberOfLines={1}>
|
|
177
|
+
{act.title}
|
|
178
|
+
</Text>
|
|
179
|
+
<Text className="text-xs text-muted" numberOfLines={1}>
|
|
180
|
+
{act.subtitle} • {act.timestamp}
|
|
181
|
+
</Text>
|
|
182
|
+
</View>
|
|
183
|
+
</View>
|
|
184
|
+
|
|
185
|
+
<View className="items-end gap-1">
|
|
186
|
+
{act.amount && (
|
|
187
|
+
<Text className="text-sm font-bold text-foreground">
|
|
188
|
+
{act.amount}
|
|
189
|
+
</Text>
|
|
190
|
+
)}
|
|
191
|
+
{act.status && (
|
|
192
|
+
<Badge variant={act.status.variant} size="sm">
|
|
193
|
+
{act.status.label}
|
|
194
|
+
</Badge>
|
|
195
|
+
)}
|
|
196
|
+
</View>
|
|
197
|
+
</View>
|
|
198
|
+
))}
|
|
199
|
+
</CardContent>
|
|
200
|
+
</Card>
|
|
201
|
+
)}
|
|
202
|
+
</View>
|
|
203
|
+
</ScrollView>
|
|
204
|
+
);
|
|
205
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./DashboardTemplate";
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import {
|
|
3
|
+
View,
|
|
4
|
+
ScrollView,
|
|
5
|
+
Pressable,
|
|
6
|
+
type ViewProps,
|
|
7
|
+
} from "react-native";
|
|
8
|
+
import { cn } from "../../utilities/cn";
|
|
9
|
+
import { Text } from "../../components/text/text";
|
|
10
|
+
import { Heading } from "../../components/text/heading";
|
|
11
|
+
import { Avatar, AvatarFallback, AvatarImage } from "../../components/avatar/avatar";
|
|
12
|
+
import { Badge } from "../../components/badge/badge";
|
|
13
|
+
import { Card } from "../../components/card/card";
|
|
14
|
+
import { Switch } from "../../components/switch/switch";
|
|
15
|
+
import { Button } from "../../components/button/button";
|
|
16
|
+
import { Separator } from "../../components/separator/separator";
|
|
17
|
+
|
|
18
|
+
export interface SettingsTemplateProps extends ViewProps {
|
|
19
|
+
user: {
|
|
20
|
+
name: string;
|
|
21
|
+
email: string;
|
|
22
|
+
avatarUrl?: string;
|
|
23
|
+
plan?: string;
|
|
24
|
+
};
|
|
25
|
+
pushNotifications?: boolean;
|
|
26
|
+
onTogglePushNotifications?: (val: boolean) => void;
|
|
27
|
+
emailNotifications?: boolean;
|
|
28
|
+
onToggleEmailNotifications?: (val: boolean) => void;
|
|
29
|
+
isDarkMode?: boolean;
|
|
30
|
+
onToggleDarkMode?: (val: boolean) => void;
|
|
31
|
+
biometricsEnabled?: boolean;
|
|
32
|
+
onToggleBiometrics?: (val: boolean) => void;
|
|
33
|
+
onEditProfile?: () => void;
|
|
34
|
+
onChangePassword?: () => void;
|
|
35
|
+
onViewTerms?: () => void;
|
|
36
|
+
onViewPrivacy?: () => void;
|
|
37
|
+
onLogout?: () => void;
|
|
38
|
+
onDeleteAccount?: () => void;
|
|
39
|
+
className?: string;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export const SettingsTemplate: React.FC<SettingsTemplateProps> = ({
|
|
43
|
+
user,
|
|
44
|
+
pushNotifications = true,
|
|
45
|
+
onTogglePushNotifications,
|
|
46
|
+
emailNotifications = true,
|
|
47
|
+
onToggleEmailNotifications,
|
|
48
|
+
isDarkMode = false,
|
|
49
|
+
onToggleDarkMode,
|
|
50
|
+
biometricsEnabled = false,
|
|
51
|
+
onToggleBiometrics,
|
|
52
|
+
onEditProfile,
|
|
53
|
+
onChangePassword,
|
|
54
|
+
onViewTerms,
|
|
55
|
+
onViewPrivacy,
|
|
56
|
+
onLogout,
|
|
57
|
+
onDeleteAccount,
|
|
58
|
+
className,
|
|
59
|
+
...props
|
|
60
|
+
}) => {
|
|
61
|
+
return (
|
|
62
|
+
<ScrollView
|
|
63
|
+
{...props}
|
|
64
|
+
style={[{ flex: 1 }, (props as any).style]}
|
|
65
|
+
className={cn("flex-1 bg-background", className)}
|
|
66
|
+
contentContainerStyle={{ paddingBottom: 40 }}
|
|
67
|
+
showsVerticalScrollIndicator={false}
|
|
68
|
+
>
|
|
69
|
+
<View className="px-6 pt-6 gap-6">
|
|
70
|
+
<Heading level={2} className="text-2xl font-bold text-foreground">
|
|
71
|
+
Settings & Profile
|
|
72
|
+
</Heading>
|
|
73
|
+
|
|
74
|
+
{/* User Card */}
|
|
75
|
+
<Card className="p-4 flex-row items-center gap-4">
|
|
76
|
+
<Avatar size="lg">
|
|
77
|
+
{user.avatarUrl && <AvatarImage source={{ uri: user.avatarUrl }} />}
|
|
78
|
+
<AvatarFallback text={user.name.slice(0, 2).toUpperCase()} />
|
|
79
|
+
</Avatar>
|
|
80
|
+
<View className="flex-1">
|
|
81
|
+
<View className="flex-row items-center gap-2">
|
|
82
|
+
<Text className="text-base font-bold text-foreground">{user.name}</Text>
|
|
83
|
+
{user.plan && (
|
|
84
|
+
<Badge variant="primary" size="sm">
|
|
85
|
+
{user.plan}
|
|
86
|
+
</Badge>
|
|
87
|
+
)}
|
|
88
|
+
</View>
|
|
89
|
+
<Text className="text-xs text-muted">{user.email}</Text>
|
|
90
|
+
</View>
|
|
91
|
+
{onEditProfile && (
|
|
92
|
+
<Button variant="outline" size="sm" onPress={onEditProfile}>
|
|
93
|
+
Edit
|
|
94
|
+
</Button>
|
|
95
|
+
)}
|
|
96
|
+
</Card>
|
|
97
|
+
|
|
98
|
+
{/* Preferences Section */}
|
|
99
|
+
<View className="gap-2">
|
|
100
|
+
<Text className="text-xs font-bold text-muted uppercase tracking-wider px-1">
|
|
101
|
+
Preferences
|
|
102
|
+
</Text>
|
|
103
|
+
<Card className="divide-y divide-border/50">
|
|
104
|
+
<View className="p-4 flex-row items-center justify-between">
|
|
105
|
+
<View className="pr-4 flex-1">
|
|
106
|
+
<Text className="text-sm font-semibold text-foreground">
|
|
107
|
+
Push Notifications
|
|
108
|
+
</Text>
|
|
109
|
+
<Text className="text-xs text-muted">
|
|
110
|
+
Receive real-time alerts on your mobile device
|
|
111
|
+
</Text>
|
|
112
|
+
</View>
|
|
113
|
+
<Switch
|
|
114
|
+
checked={pushNotifications}
|
|
115
|
+
onCheckedChange={onTogglePushNotifications}
|
|
116
|
+
/>
|
|
117
|
+
</View>
|
|
118
|
+
|
|
119
|
+
<View className="p-4 flex-row items-center justify-between">
|
|
120
|
+
<View className="pr-4 flex-1">
|
|
121
|
+
<Text className="text-sm font-semibold text-foreground">
|
|
122
|
+
Email Notifications
|
|
123
|
+
</Text>
|
|
124
|
+
<Text className="text-xs text-muted">
|
|
125
|
+
Weekly digests and activity summaries
|
|
126
|
+
</Text>
|
|
127
|
+
</View>
|
|
128
|
+
<Switch
|
|
129
|
+
checked={emailNotifications}
|
|
130
|
+
onCheckedChange={onToggleEmailNotifications}
|
|
131
|
+
/>
|
|
132
|
+
</View>
|
|
133
|
+
|
|
134
|
+
<View className="p-4 flex-row items-center justify-between">
|
|
135
|
+
<View className="pr-4 flex-1">
|
|
136
|
+
<Text className="text-sm font-semibold text-foreground">Dark Theme</Text>
|
|
137
|
+
<Text className="text-xs text-muted">
|
|
138
|
+
Enable high contrast dark mode appearance
|
|
139
|
+
</Text>
|
|
140
|
+
</View>
|
|
141
|
+
<Switch checked={isDarkMode} onCheckedChange={onToggleDarkMode} />
|
|
142
|
+
</View>
|
|
143
|
+
|
|
144
|
+
<View className="p-4 flex-row items-center justify-between">
|
|
145
|
+
<View className="pr-4 flex-1">
|
|
146
|
+
<Text className="text-sm font-semibold text-foreground">
|
|
147
|
+
Biometric Login
|
|
148
|
+
</Text>
|
|
149
|
+
<Text className="text-xs text-muted">
|
|
150
|
+
Use Face ID or fingerprint to authenticate
|
|
151
|
+
</Text>
|
|
152
|
+
</View>
|
|
153
|
+
<Switch
|
|
154
|
+
checked={biometricsEnabled}
|
|
155
|
+
onCheckedChange={onToggleBiometrics}
|
|
156
|
+
/>
|
|
157
|
+
</View>
|
|
158
|
+
</Card>
|
|
159
|
+
</View>
|
|
160
|
+
|
|
161
|
+
{/* Security & Account Links */}
|
|
162
|
+
<View className="gap-2">
|
|
163
|
+
<Text className="text-xs font-bold text-muted uppercase tracking-wider px-1">
|
|
164
|
+
Account & Security
|
|
165
|
+
</Text>
|
|
166
|
+
<Card className="divide-y divide-border/50">
|
|
167
|
+
{onChangePassword && (
|
|
168
|
+
<Pressable
|
|
169
|
+
onPress={onChangePassword}
|
|
170
|
+
className="p-4 flex-row items-center justify-between active:bg-muted/10"
|
|
171
|
+
>
|
|
172
|
+
<Text className="text-sm font-semibold text-foreground">
|
|
173
|
+
Change Password
|
|
174
|
+
</Text>
|
|
175
|
+
<Text className="text-muted text-xs">›</Text>
|
|
176
|
+
</Pressable>
|
|
177
|
+
)}
|
|
178
|
+
|
|
179
|
+
{onViewTerms && (
|
|
180
|
+
<Pressable
|
|
181
|
+
onPress={onViewTerms}
|
|
182
|
+
className="p-4 flex-row items-center justify-between active:bg-muted/10"
|
|
183
|
+
>
|
|
184
|
+
<Text className="text-sm font-semibold text-foreground">
|
|
185
|
+
Terms of Service
|
|
186
|
+
</Text>
|
|
187
|
+
<Text className="text-muted text-xs">›</Text>
|
|
188
|
+
</Pressable>
|
|
189
|
+
)}
|
|
190
|
+
|
|
191
|
+
{onViewPrivacy && (
|
|
192
|
+
<Pressable
|
|
193
|
+
onPress={onViewPrivacy}
|
|
194
|
+
className="p-4 flex-row items-center justify-between active:bg-muted/10"
|
|
195
|
+
>
|
|
196
|
+
<Text className="text-sm font-semibold text-foreground">
|
|
197
|
+
Privacy Policy
|
|
198
|
+
</Text>
|
|
199
|
+
<Text className="text-muted text-xs">›</Text>
|
|
200
|
+
</Pressable>
|
|
201
|
+
)}
|
|
202
|
+
</Card>
|
|
203
|
+
</View>
|
|
204
|
+
|
|
205
|
+
{/* Danger Zone */}
|
|
206
|
+
<View className="gap-3 pt-2">
|
|
207
|
+
{onLogout && (
|
|
208
|
+
<Button variant="outline" size="lg" onPress={onLogout}>
|
|
209
|
+
Log Out
|
|
210
|
+
</Button>
|
|
211
|
+
)}
|
|
212
|
+
|
|
213
|
+
{onDeleteAccount && (
|
|
214
|
+
<Button
|
|
215
|
+
variant="destructive"
|
|
216
|
+
size="lg"
|
|
217
|
+
onPress={onDeleteAccount}
|
|
218
|
+
>
|
|
219
|
+
Delete Account
|
|
220
|
+
</Button>
|
|
221
|
+
)}
|
|
222
|
+
</View>
|
|
223
|
+
</View>
|
|
224
|
+
</ScrollView>
|
|
225
|
+
);
|
|
226
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./SettingsTemplate";
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { tokens } from "./tokens";
|
|
2
|
+
|
|
3
|
+
export { tokens };
|
|
4
|
+
|
|
5
|
+
export const beyondUIPreset = {
|
|
6
|
+
darkMode: "class",
|
|
7
|
+
theme: {
|
|
8
|
+
extend: {
|
|
9
|
+
colors: {
|
|
10
|
+
primary: tokens.colors.primary,
|
|
11
|
+
secondary: tokens.colors.secondary,
|
|
12
|
+
danger: tokens.colors.danger,
|
|
13
|
+
destructive: tokens.colors.destructive,
|
|
14
|
+
success: tokens.colors.success,
|
|
15
|
+
warning: tokens.colors.warning,
|
|
16
|
+
neutral: tokens.colors.neutral,
|
|
17
|
+
background: tokens.colors.semantic.light.background,
|
|
18
|
+
foreground: tokens.colors.semantic.light.foreground,
|
|
19
|
+
card: {
|
|
20
|
+
DEFAULT: tokens.colors.semantic.light.card,
|
|
21
|
+
foreground: tokens.colors.semantic.light.cardForeground,
|
|
22
|
+
},
|
|
23
|
+
cardForeground: tokens.colors.semantic.light.cardForeground,
|
|
24
|
+
muted: {
|
|
25
|
+
DEFAULT: tokens.colors.semantic.light.mutedForeground,
|
|
26
|
+
foreground: tokens.colors.semantic.light.mutedForeground,
|
|
27
|
+
},
|
|
28
|
+
mutedForeground: tokens.colors.semantic.light.mutedForeground,
|
|
29
|
+
border: tokens.colors.semantic.light.border,
|
|
30
|
+
input: tokens.colors.semantic.light.input,
|
|
31
|
+
},
|
|
32
|
+
borderRadius: {
|
|
33
|
+
none: "0px",
|
|
34
|
+
sm: `${tokens.radius.sm}px`,
|
|
35
|
+
md: `${tokens.radius.md}px`,
|
|
36
|
+
lg: `${tokens.radius.lg}px`,
|
|
37
|
+
xl: `${tokens.radius.xl}px`,
|
|
38
|
+
"2xl": `${tokens.radius["2xl"]}px`,
|
|
39
|
+
full: "9999px",
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export default beyondUIPreset;
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
export const tokens = {
|
|
2
|
+
colors: {
|
|
3
|
+
primary: {
|
|
4
|
+
50: "#eff6ff",
|
|
5
|
+
100: "#dbeafe",
|
|
6
|
+
200: "#bfdbfe",
|
|
7
|
+
300: "#93c5fd",
|
|
8
|
+
400: "#60a5fa",
|
|
9
|
+
500: "#3b82f6",
|
|
10
|
+
600: "#2563eb",
|
|
11
|
+
700: "#1d4ed8",
|
|
12
|
+
800: "#1e40af",
|
|
13
|
+
900: "#1e3a8a",
|
|
14
|
+
950: "#172554",
|
|
15
|
+
DEFAULT: "#2563eb",
|
|
16
|
+
},
|
|
17
|
+
secondary: {
|
|
18
|
+
50: "#f8fafc",
|
|
19
|
+
100: "#f1f5f9",
|
|
20
|
+
200: "#e2e8f0",
|
|
21
|
+
300: "#cbd5e1",
|
|
22
|
+
400: "#94a3b8",
|
|
23
|
+
500: "#64748b",
|
|
24
|
+
600: "#475569",
|
|
25
|
+
700: "#334155",
|
|
26
|
+
800: "#1e293b",
|
|
27
|
+
900: "#0f172a",
|
|
28
|
+
950: "#020617",
|
|
29
|
+
DEFAULT: "#475569",
|
|
30
|
+
},
|
|
31
|
+
danger: {
|
|
32
|
+
50: "#fef2f2",
|
|
33
|
+
100: "#fee2e2",
|
|
34
|
+
200: "#fecaca",
|
|
35
|
+
300: "#fca5a5",
|
|
36
|
+
400: "#f87171",
|
|
37
|
+
500: "#ef4444",
|
|
38
|
+
600: "#dc2626",
|
|
39
|
+
700: "#b91c1c",
|
|
40
|
+
800: "#991b1b",
|
|
41
|
+
900: "#7f1d1d",
|
|
42
|
+
950: "#450a0a",
|
|
43
|
+
DEFAULT: "#dc2626",
|
|
44
|
+
},
|
|
45
|
+
// Alias for shadcn / React Native convention compatibility
|
|
46
|
+
destructive: {
|
|
47
|
+
50: "#fef2f2",
|
|
48
|
+
100: "#fee2e2",
|
|
49
|
+
200: "#fecaca",
|
|
50
|
+
300: "#fca5a5",
|
|
51
|
+
400: "#f87171",
|
|
52
|
+
500: "#ef4444",
|
|
53
|
+
600: "#dc2626",
|
|
54
|
+
700: "#b91c1c",
|
|
55
|
+
800: "#991b1b",
|
|
56
|
+
900: "#7f1d1d",
|
|
57
|
+
950: "#450a0a",
|
|
58
|
+
DEFAULT: "#dc2626",
|
|
59
|
+
},
|
|
60
|
+
success: {
|
|
61
|
+
50: "#f0fdf4",
|
|
62
|
+
100: "#dcfce7",
|
|
63
|
+
200: "#bbf7d0",
|
|
64
|
+
300: "#86efac",
|
|
65
|
+
400: "#4ade80",
|
|
66
|
+
500: "#22c55e",
|
|
67
|
+
600: "#16a34a",
|
|
68
|
+
700: "#15803d",
|
|
69
|
+
800: "#166534",
|
|
70
|
+
900: "#14532d",
|
|
71
|
+
950: "#052e16",
|
|
72
|
+
DEFAULT: "#16a34a",
|
|
73
|
+
},
|
|
74
|
+
warning: {
|
|
75
|
+
50: "#fffbeb",
|
|
76
|
+
100: "#fef3c7",
|
|
77
|
+
200: "#fde68a",
|
|
78
|
+
300: "#fcd34d",
|
|
79
|
+
400: "#fbbf24",
|
|
80
|
+
500: "#f59e0b",
|
|
81
|
+
600: "#d97706",
|
|
82
|
+
700: "#b45309",
|
|
83
|
+
800: "#92400e",
|
|
84
|
+
900: "#78350f",
|
|
85
|
+
950: "#451a03",
|
|
86
|
+
DEFAULT: "#d97706",
|
|
87
|
+
},
|
|
88
|
+
neutral: {
|
|
89
|
+
50: "#f9fafb",
|
|
90
|
+
100: "#f3f4f6",
|
|
91
|
+
200: "#e5e7eb",
|
|
92
|
+
300: "#d1d5db",
|
|
93
|
+
400: "#9ca3af",
|
|
94
|
+
500: "#6b7280",
|
|
95
|
+
600: "#4b5563",
|
|
96
|
+
700: "#374151",
|
|
97
|
+
800: "#1f2937",
|
|
98
|
+
900: "#111827",
|
|
99
|
+
950: "#030712",
|
|
100
|
+
},
|
|
101
|
+
semantic: {
|
|
102
|
+
light: {
|
|
103
|
+
background: "#ffffff",
|
|
104
|
+
foreground: "#0f172a",
|
|
105
|
+
card: "#ffffff",
|
|
106
|
+
cardForeground: "#0f172a",
|
|
107
|
+
muted: "#f8fafc",
|
|
108
|
+
mutedForeground: "#64748b",
|
|
109
|
+
border: "#e2e8f0",
|
|
110
|
+
input: "#e2e8f0",
|
|
111
|
+
},
|
|
112
|
+
dark: {
|
|
113
|
+
background: "#090d16",
|
|
114
|
+
foreground: "#f8fafc",
|
|
115
|
+
card: "#0f172a",
|
|
116
|
+
cardForeground: "#f8fafc",
|
|
117
|
+
muted: "#1e293b",
|
|
118
|
+
mutedForeground: "#94a3b8",
|
|
119
|
+
border: "#334155",
|
|
120
|
+
input: "#334155",
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
},
|
|
124
|
+
radius: {
|
|
125
|
+
none: 0,
|
|
126
|
+
sm: 6,
|
|
127
|
+
md: 10,
|
|
128
|
+
lg: 14,
|
|
129
|
+
xl: 20,
|
|
130
|
+
"2xl": 28,
|
|
131
|
+
full: 9999,
|
|
132
|
+
},
|
|
133
|
+
spacing: {
|
|
134
|
+
xs: 4,
|
|
135
|
+
sm: 8,
|
|
136
|
+
md: 12,
|
|
137
|
+
lg: 16,
|
|
138
|
+
xl: 24,
|
|
139
|
+
"2xl": 32,
|
|
140
|
+
"3xl": 48,
|
|
141
|
+
},
|
|
142
|
+
} as const;
|
|
143
|
+
|
|
144
|
+
export type BeyondUITokens = typeof tokens;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/// <reference types="nativewind/types" />
|
|
2
|
+
|
|
3
|
+
import "react-native";
|
|
4
|
+
|
|
5
|
+
declare module "react-native" {
|
|
6
|
+
interface ViewProps {
|
|
7
|
+
className?: string;
|
|
8
|
+
}
|
|
9
|
+
interface TextProps {
|
|
10
|
+
className?: string;
|
|
11
|
+
}
|
|
12
|
+
interface TextInputProps {
|
|
13
|
+
className?: string;
|
|
14
|
+
placeholderClassName?: string;
|
|
15
|
+
}
|
|
16
|
+
interface PressableProps {
|
|
17
|
+
className?: string;
|
|
18
|
+
}
|
|
19
|
+
interface ScrollViewProps {
|
|
20
|
+
className?: string;
|
|
21
|
+
contentContainerClassName?: string;
|
|
22
|
+
}
|
|
23
|
+
interface ImageProps {
|
|
24
|
+
className?: string;
|
|
25
|
+
}
|
|
26
|
+
}
|