expo-bbase 1.6.1 → 1.7.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.js +242 -315
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2527,19 +2527,6 @@ var uiReusablesModule = {
|
|
|
2527
2527
|
},
|
|
2528
2528
|
devDependencies: {},
|
|
2529
2529
|
files: [
|
|
2530
|
-
// ─── lib/utils.ts ────────────────────────────────────────────────────
|
|
2531
|
-
{
|
|
2532
|
-
path: "lib/utils.ts",
|
|
2533
|
-
content: lines(
|
|
2534
|
-
'import { type ClassValue, clsx } from "clsx";',
|
|
2535
|
-
'import { twMerge } from "tailwind-merge";',
|
|
2536
|
-
"",
|
|
2537
|
-
"export function cn(...inputs: ClassValue[]) {",
|
|
2538
|
-
" return twMerge(clsx(inputs));",
|
|
2539
|
-
"}",
|
|
2540
|
-
""
|
|
2541
|
-
)
|
|
2542
|
-
},
|
|
2543
2530
|
// ─── components/ui/text.tsx ──────────────────────────────────────────
|
|
2544
2531
|
{
|
|
2545
2532
|
path: "components/ui/text.tsx",
|
|
@@ -3152,8 +3139,8 @@ import { Stack } from "expo-router";
|
|
|
3152
3139
|
import * as SplashScreen from "expo-splash-screen";
|
|
3153
3140
|
import { useEffect } from "react";
|
|
3154
3141
|
import { useColorScheme } from "react-native";
|
|
3155
|
-
|
|
3156
|
-
import {
|
|
3142
|
+
import { PortalHost } from "@rn-primitives/portal";
|
|
3143
|
+
import { NAV_THEME } from "@/lib/theme";
|
|
3157
3144
|
|
|
3158
3145
|
SplashScreen.preventAutoHideAsync();
|
|
3159
3146
|
|
|
@@ -3174,11 +3161,13 @@ export default function RootLayout() {
|
|
|
3174
3161
|
}
|
|
3175
3162
|
|
|
3176
3163
|
return (
|
|
3177
|
-
<ThemeProvider value={colorScheme === "dark" ?
|
|
3164
|
+
<ThemeProvider value={colorScheme === "dark" ? NAV_THEME.dark : NAV_THEME.light}>
|
|
3165
|
+
<StatusBar style={colorScheme === "dark" ? "light" : "dark"} />
|
|
3178
3166
|
<Stack>
|
|
3179
3167
|
<Stack.Screen name="(tabs)" options={{ headerShown: false }} />
|
|
3180
3168
|
<Stack.Screen name="+not-found" />
|
|
3181
3169
|
</Stack>
|
|
3170
|
+
<PortalHost />
|
|
3182
3171
|
</ThemeProvider>
|
|
3183
3172
|
);
|
|
3184
3173
|
}
|
|
@@ -3190,19 +3179,10 @@ export default function RootLayout() {
|
|
|
3190
3179
|
content: `import { Tabs } from "expo-router";
|
|
3191
3180
|
import { Platform } from "react-native";
|
|
3192
3181
|
|
|
3193
|
-
import { Colors } from "@/constants/Colors";
|
|
3194
|
-
import { useColorScheme } from "@/hooks/useColorScheme";
|
|
3195
|
-
|
|
3196
3182
|
export default function TabLayout() {
|
|
3197
|
-
const colorScheme = useColorScheme();
|
|
3198
|
-
|
|
3199
3183
|
return (
|
|
3200
3184
|
<Tabs
|
|
3201
3185
|
screenOptions={{
|
|
3202
|
-
tabBarActiveTintColor: Colors[colorScheme ?? "light"].tint,
|
|
3203
|
-
headerStyle: {
|
|
3204
|
-
backgroundColor: Colors[colorScheme ?? "light"].background,
|
|
3205
|
-
},
|
|
3206
3186
|
headerShadowVisible: false,
|
|
3207
3187
|
tabBarStyle: Platform.select({
|
|
3208
3188
|
ios: {
|
|
@@ -3234,258 +3214,152 @@ export default function TabLayout() {
|
|
|
3234
3214
|
// ─── app/(tabs)/index.tsx ───────────────────────────────────────────
|
|
3235
3215
|
{
|
|
3236
3216
|
path: "app/(tabs)/index.tsx",
|
|
3237
|
-
content: `import {
|
|
3238
|
-
import { HelloWave } from "@/components/HelloWave";
|
|
3239
|
-
import { ThemedText } from "@/components/Themed";
|
|
3240
|
-
import { ThemedView } from "@/components/Themed";
|
|
3241
|
-
import { Link } from "expo-router";
|
|
3217
|
+
content: `import { Text, View } from "react-native";
|
|
3242
3218
|
|
|
3243
3219
|
export default function HomeScreen() {
|
|
3244
3220
|
return (
|
|
3245
|
-
<
|
|
3246
|
-
<
|
|
3247
|
-
|
|
3248
|
-
|
|
3249
|
-
</ThemedView>
|
|
3250
|
-
<ThemedView style={styles.stepContainer}>
|
|
3251
|
-
<ThemedText type="subtitle">Step 1: Try it</ThemedText>
|
|
3252
|
-
<ThemedText>
|
|
3253
|
-
Edit <ThemedText type="defaultSemiBold">app/(tabs)/index.tsx</ThemedText> to see changes.
|
|
3254
|
-
Press{" "}
|
|
3255
|
-
<ThemedText type="defaultSemiBold">
|
|
3256
|
-
{Platform.select({ ios: "cmd + d", android: "cmd + m" })}
|
|
3257
|
-
</ThemedText>{" "}
|
|
3258
|
-
to open developer tools.
|
|
3259
|
-
</ThemedText>
|
|
3260
|
-
</ThemedView>
|
|
3261
|
-
<ThemedView style={styles.stepContainer}>
|
|
3262
|
-
<ThemedText type="subtitle">Step 2: Explore</ThemedText>
|
|
3263
|
-
<ThemedText>
|
|
3264
|
-
Tap the Explore tab to learn more about what's included in this starter.
|
|
3265
|
-
</ThemedText>
|
|
3266
|
-
<Link href="/explore">
|
|
3267
|
-
<ThemedText type="link">Go to Explore \u2192</ThemedText>
|
|
3268
|
-
</Link>
|
|
3269
|
-
</ThemedView>
|
|
3270
|
-
</ThemedView>
|
|
3221
|
+
<View className="flex-1 items-center justify-center p-6">
|
|
3222
|
+
<Text className="text-foreground text-2xl font-bold">${projectName}</Text>
|
|
3223
|
+
<Text className="text-muted-foreground mt-2">Welcome to your new app</Text>
|
|
3224
|
+
</View>
|
|
3271
3225
|
);
|
|
3272
3226
|
}
|
|
3273
|
-
|
|
3274
|
-
const styles = StyleSheet.create({
|
|
3275
|
-
container: {
|
|
3276
|
-
flex: 1,
|
|
3277
|
-
alignItems: "center",
|
|
3278
|
-
justifyContent: "center",
|
|
3279
|
-
},
|
|
3280
|
-
titleContainer: {
|
|
3281
|
-
flexDirection: "row",
|
|
3282
|
-
alignItems: "center",
|
|
3283
|
-
gap: 8,
|
|
3284
|
-
},
|
|
3285
|
-
stepContainer: {
|
|
3286
|
-
gap: 8,
|
|
3287
|
-
marginBottom: 8,
|
|
3288
|
-
},
|
|
3289
|
-
});
|
|
3290
3227
|
`
|
|
3291
3228
|
},
|
|
3292
3229
|
// ─── app/(tabs)/explore.tsx ─────────────────────────────────────────
|
|
3293
3230
|
{
|
|
3294
3231
|
path: "app/(tabs)/explore.tsx",
|
|
3295
|
-
content: `import {
|
|
3296
|
-
import { ThemedText } from "@/components/Themed";
|
|
3297
|
-
import { ThemedView } from "@/components/Themed";
|
|
3232
|
+
content: `import { Text, View } from "react-native";
|
|
3298
3233
|
|
|
3299
3234
|
export default function ExploreScreen() {
|
|
3300
3235
|
return (
|
|
3301
|
-
<
|
|
3302
|
-
<
|
|
3303
|
-
<
|
|
3304
|
-
|
|
3305
|
-
</ThemedText>
|
|
3306
|
-
</ThemedView>
|
|
3236
|
+
<View className="flex-1 items-center justify-center p-6">
|
|
3237
|
+
<Text className="text-foreground text-2xl font-bold">Explore</Text>
|
|
3238
|
+
<Text className="text-muted-foreground mt-2">Discover new features</Text>
|
|
3239
|
+
</View>
|
|
3307
3240
|
);
|
|
3308
3241
|
}
|
|
3309
|
-
|
|
3310
|
-
const styles = StyleSheet.create({
|
|
3311
|
-
container: {
|
|
3312
|
-
flex: 1,
|
|
3313
|
-
alignItems: "center",
|
|
3314
|
-
justifyContent: "center",
|
|
3315
|
-
},
|
|
3316
|
-
subtitle: {
|
|
3317
|
-
fontSize: 16,
|
|
3318
|
-
textAlign: "center",
|
|
3319
|
-
marginTop: 8,
|
|
3320
|
-
},
|
|
3321
|
-
});
|
|
3322
3242
|
`
|
|
3323
3243
|
},
|
|
3324
3244
|
// ─── app/+not-found.tsx ─────────────────────────────────────────────
|
|
3325
3245
|
{
|
|
3326
3246
|
path: "app/+not-found.tsx",
|
|
3327
3247
|
content: `import { Link, Stack } from "expo-router";
|
|
3328
|
-
import {
|
|
3329
|
-
import { ThemedText } from "@/components/Themed";
|
|
3330
|
-
import { ThemedView } from "@/components/Themed";
|
|
3248
|
+
import { Text, View } from "react-native";
|
|
3331
3249
|
|
|
3332
3250
|
export default function NotFoundScreen() {
|
|
3333
3251
|
return (
|
|
3334
3252
|
<>
|
|
3335
3253
|
<Stack.Screen options={{ title: "Oops!" }} />
|
|
3336
|
-
<
|
|
3337
|
-
<
|
|
3338
|
-
<Link href="/"
|
|
3339
|
-
<
|
|
3254
|
+
<View className="flex-1 items-center justify-center p-5">
|
|
3255
|
+
<Text className="text-foreground text-2xl font-bold">This screen doesn't exist.</Text>
|
|
3256
|
+
<Link href="/" className="mt-4 py-4">
|
|
3257
|
+
<Text className="text-primary underline">Go to home screen!</Text>
|
|
3340
3258
|
</Link>
|
|
3341
|
-
</
|
|
3259
|
+
</View>
|
|
3342
3260
|
</>
|
|
3343
3261
|
);
|
|
3344
3262
|
}
|
|
3345
|
-
|
|
3346
|
-
const styles = StyleSheet.create({
|
|
3347
|
-
container: {
|
|
3348
|
-
flex: 1,
|
|
3349
|
-
alignItems: "center",
|
|
3350
|
-
justifyContent: "center",
|
|
3351
|
-
padding: 20,
|
|
3352
|
-
},
|
|
3353
|
-
link: {
|
|
3354
|
-
marginTop: 15,
|
|
3355
|
-
paddingVertical: 15,
|
|
3356
|
-
},
|
|
3357
|
-
});
|
|
3358
3263
|
`
|
|
3359
3264
|
},
|
|
3360
|
-
// ───
|
|
3265
|
+
// ─── lib/utils.ts (rnr official cn helper) ───────────────────────────
|
|
3361
3266
|
{
|
|
3362
|
-
path: "
|
|
3363
|
-
content: `import {
|
|
3364
|
-
import {
|
|
3365
|
-
import { Colors } from "@/constants/Colors";
|
|
3366
|
-
|
|
3367
|
-
/** Themed text component that adapts to light/dark mode */
|
|
3368
|
-
export function ThemedText({
|
|
3369
|
-
style,
|
|
3370
|
-
type = "default",
|
|
3371
|
-
...rest
|
|
3372
|
-
}: TextProps & { type?: "default" | "title" | "defaultSemiBold" | "subtitle" | "link" }) {
|
|
3373
|
-
const colorScheme = useColorScheme();
|
|
3374
|
-
const color = Colors[colorScheme ?? "light"].text;
|
|
3375
|
-
|
|
3376
|
-
return (
|
|
3377
|
-
<Text
|
|
3378
|
-
style={[
|
|
3379
|
-
{ color },
|
|
3380
|
-
type === "default" ? { fontSize: 16, lineHeight: 24 } : undefined,
|
|
3381
|
-
type === "title" ? { fontSize: 28, fontWeight: "bold", lineHeight: 32 } : undefined,
|
|
3382
|
-
type === "defaultSemiBold" ? { fontSize: 16, lineHeight: 24, fontWeight: "600" } : undefined,
|
|
3383
|
-
type === "subtitle" ? { fontSize: 20, fontWeight: "bold" } : undefined,
|
|
3384
|
-
type === "link" ? { fontSize: 16, lineHeight: 24, color: Colors[colorScheme ?? "light"].tint } : undefined,
|
|
3385
|
-
style,
|
|
3386
|
-
]}
|
|
3387
|
-
{...rest}
|
|
3388
|
-
/>
|
|
3389
|
-
);
|
|
3390
|
-
}
|
|
3391
|
-
|
|
3392
|
-
/** Themed view component that adapts to light/dark mode */
|
|
3393
|
-
export function ThemedView({ style, ...rest }: ViewProps) {
|
|
3394
|
-
const colorScheme = useColorScheme();
|
|
3395
|
-
const backgroundColor = Colors[colorScheme ?? "light"].background;
|
|
3267
|
+
path: "lib/utils.ts",
|
|
3268
|
+
content: `import { clsx, type ClassValue } from "clsx";
|
|
3269
|
+
import { twMerge } from "tailwind-merge";
|
|
3396
3270
|
|
|
3397
|
-
|
|
3271
|
+
export function cn(...inputs: ClassValue[]) {
|
|
3272
|
+
return twMerge(clsx(inputs));
|
|
3398
3273
|
}
|
|
3399
3274
|
`
|
|
3400
3275
|
},
|
|
3401
|
-
// ───
|
|
3276
|
+
// ─── lib/theme.ts (rnr official theme) ───────────────────────────────
|
|
3402
3277
|
{
|
|
3403
|
-
path: "
|
|
3404
|
-
content: `import {
|
|
3405
|
-
import { Animated, Easing } from "react-native";
|
|
3406
|
-
import { ThemedText } from "./Themed";
|
|
3407
|
-
|
|
3408
|
-
export function HelloWave() {
|
|
3409
|
-
const rotationAnim = new Animated.Value(0);
|
|
3278
|
+
path: "lib/theme.ts",
|
|
3279
|
+
content: `import { DarkTheme, DefaultTheme, type Theme } from '@react-navigation/native';
|
|
3410
3280
|
|
|
3411
|
-
|
|
3412
|
-
|
|
3413
|
-
|
|
3414
|
-
|
|
3415
|
-
|
|
3416
|
-
|
|
3417
|
-
|
|
3418
|
-
|
|
3419
|
-
|
|
3420
|
-
|
|
3421
|
-
|
|
3422
|
-
|
|
3423
|
-
|
|
3424
|
-
|
|
3425
|
-
|
|
3426
|
-
|
|
3427
|
-
|
|
3428
|
-
|
|
3429
|
-
|
|
3430
|
-
|
|
3431
|
-
|
|
3432
|
-
|
|
3433
|
-
|
|
3434
|
-
|
|
3435
|
-
|
|
3436
|
-
|
|
3437
|
-
|
|
3438
|
-
|
|
3439
|
-
|
|
3440
|
-
|
|
3441
|
-
|
|
3442
|
-
|
|
3443
|
-
|
|
3444
|
-
|
|
3445
|
-
|
|
3446
|
-
|
|
3447
|
-
|
|
3448
|
-
|
|
3449
|
-
|
|
3450
|
-
|
|
3451
|
-
|
|
3452
|
-
|
|
3281
|
+
export const THEME = {
|
|
3282
|
+
light: {
|
|
3283
|
+
background: 'hsl(0 0% 100%)',
|
|
3284
|
+
foreground: 'hsl(0 0% 3.9%)',
|
|
3285
|
+
card: 'hsl(0 0% 100%)',
|
|
3286
|
+
cardForeground: 'hsl(0 0% 3.9%)',
|
|
3287
|
+
popover: 'hsl(0 0% 100%)',
|
|
3288
|
+
popoverForeground: 'hsl(0 0% 3.9%)',
|
|
3289
|
+
primary: 'hsl(0 0% 9%)',
|
|
3290
|
+
primaryForeground: 'hsl(0 0% 98%)',
|
|
3291
|
+
secondary: 'hsl(0 0% 96.1%)',
|
|
3292
|
+
secondaryForeground: 'hsl(0 0% 9%)',
|
|
3293
|
+
muted: 'hsl(0 0% 96.1%)',
|
|
3294
|
+
mutedForeground: 'hsl(0 0% 45.1%)',
|
|
3295
|
+
accent: 'hsl(0 0% 96.1%)',
|
|
3296
|
+
accentForeground: 'hsl(0 0% 9%)',
|
|
3297
|
+
destructive: 'hsl(0 84.2% 60.2%)',
|
|
3298
|
+
border: 'hsl(0 0% 89.8%)',
|
|
3299
|
+
input: 'hsl(0 0% 89.8%)',
|
|
3300
|
+
ring: 'hsl(0 0% 63%)',
|
|
3301
|
+
radius: '0.625rem',
|
|
3302
|
+
chart1: 'hsl(12 76% 61%)',
|
|
3303
|
+
chart2: 'hsl(173 58% 39%)',
|
|
3304
|
+
chart3: 'hsl(197 37% 24%)',
|
|
3305
|
+
chart4: 'hsl(43 74% 66%)',
|
|
3306
|
+
chart5: 'hsl(27 87% 67%)',
|
|
3307
|
+
},
|
|
3308
|
+
dark: {
|
|
3309
|
+
background: 'hsl(0 0% 3.9%)',
|
|
3310
|
+
foreground: 'hsl(0 0% 98%)',
|
|
3311
|
+
card: 'hsl(0 0% 3.9%)',
|
|
3312
|
+
cardForeground: 'hsl(0 0% 98%)',
|
|
3313
|
+
popover: 'hsl(0 0% 3.9%)',
|
|
3314
|
+
popoverForeground: 'hsl(0 0% 98%)',
|
|
3315
|
+
primary: 'hsl(0 0% 98%)',
|
|
3316
|
+
primaryForeground: 'hsl(0 0% 9%)',
|
|
3317
|
+
secondary: 'hsl(0 0% 14.9%)',
|
|
3318
|
+
secondaryForeground: 'hsl(0 0% 98%)',
|
|
3319
|
+
muted: 'hsl(0 0% 14.9%)',
|
|
3320
|
+
mutedForeground: 'hsl(0 0% 63.9%)',
|
|
3321
|
+
accent: 'hsl(0 0% 14.9%)',
|
|
3322
|
+
accentForeground: 'hsl(0 0% 98%)',
|
|
3323
|
+
destructive: 'hsl(0 70.9% 59.4%)',
|
|
3324
|
+
border: 'hsl(0 0% 14.9%)',
|
|
3325
|
+
input: 'hsl(0 0% 14.9%)',
|
|
3326
|
+
ring: 'hsl(300 0% 45%)',
|
|
3327
|
+
radius: '0.625rem',
|
|
3328
|
+
chart1: 'hsl(220 70% 50%)',
|
|
3329
|
+
chart2: 'hsl(160 60% 45%)',
|
|
3330
|
+
chart3: 'hsl(30 80% 55%)',
|
|
3331
|
+
chart4: 'hsl(280 65% 60%)',
|
|
3332
|
+
chart5: 'hsl(340 75% 55%)',
|
|
3333
|
+
},
|
|
3334
|
+
};
|
|
3453
3335
|
|
|
3454
|
-
|
|
3455
|
-
* Returns the current color scheme (light or dark).
|
|
3456
|
-
* Defaults to "light" if the system preference is not available.
|
|
3457
|
-
*/
|
|
3458
|
-
export function useColorScheme(): "light" | "dark" {
|
|
3459
|
-
return useRNColorScheme() ?? "light";
|
|
3460
|
-
}
|
|
3461
|
-
`
|
|
3462
|
-
},
|
|
3463
|
-
// ─── src/constants/Colors.ts ─────────────────────────────────────────
|
|
3464
|
-
{
|
|
3465
|
-
path: "constants/Colors.ts",
|
|
3466
|
-
content: `/**
|
|
3467
|
-
* Color tokens for light and dark themes.
|
|
3468
|
-
* Used by Themed components and navigation theming.
|
|
3469
|
-
*/
|
|
3470
|
-
export const Colors = {
|
|
3336
|
+
export const NAV_THEME: Record<'light' | 'dark', Theme> = {
|
|
3471
3337
|
light: {
|
|
3472
|
-
|
|
3473
|
-
|
|
3474
|
-
|
|
3475
|
-
|
|
3476
|
-
|
|
3338
|
+
...DefaultTheme,
|
|
3339
|
+
colors: {
|
|
3340
|
+
background: THEME.light.background,
|
|
3341
|
+
border: THEME.light.border,
|
|
3342
|
+
card: THEME.light.card,
|
|
3343
|
+
notification: THEME.light.destructive,
|
|
3344
|
+
primary: THEME.light.primary,
|
|
3345
|
+
text: THEME.light.foreground,
|
|
3346
|
+
},
|
|
3477
3347
|
},
|
|
3478
3348
|
dark: {
|
|
3479
|
-
|
|
3480
|
-
|
|
3481
|
-
|
|
3482
|
-
|
|
3483
|
-
|
|
3349
|
+
...DarkTheme,
|
|
3350
|
+
colors: {
|
|
3351
|
+
background: THEME.dark.background,
|
|
3352
|
+
border: THEME.dark.border,
|
|
3353
|
+
card: THEME.dark.card,
|
|
3354
|
+
notification: THEME.dark.destructive,
|
|
3355
|
+
primary: THEME.dark.primary,
|
|
3356
|
+
text: THEME.dark.foreground,
|
|
3357
|
+
},
|
|
3484
3358
|
},
|
|
3485
3359
|
};
|
|
3486
3360
|
`
|
|
3487
3361
|
},
|
|
3488
|
-
// ───
|
|
3362
|
+
// ─── types/index.ts ─────────────────────────────────────────────────
|
|
3489
3363
|
{
|
|
3490
3364
|
path: "types/index.ts",
|
|
3491
3365
|
content: `/** Global type definitions */
|
|
@@ -3543,6 +3417,7 @@ export {};
|
|
|
3543
3417
|
"extends": "expo/tsconfig.base",
|
|
3544
3418
|
"compilerOptions": {
|
|
3545
3419
|
"strict": true,
|
|
3420
|
+
"baseUrl": ".",
|
|
3546
3421
|
"paths": {
|
|
3547
3422
|
"@/*": ["./*"]
|
|
3548
3423
|
}
|
|
@@ -3551,61 +3426,109 @@ export {};
|
|
|
3551
3426
|
}
|
|
3552
3427
|
`
|
|
3553
3428
|
},
|
|
3554
|
-
// ───
|
|
3429
|
+
// ─── components.json (rnr CLI compatibility) ─────────────────────────
|
|
3430
|
+
{
|
|
3431
|
+
path: "components.json",
|
|
3432
|
+
content: `{
|
|
3433
|
+
"$schema": "https://ui.shadcn.com/schema.json",
|
|
3434
|
+
"style": "new-york",
|
|
3435
|
+
"rsc": false,
|
|
3436
|
+
"tsx": true,
|
|
3437
|
+
"tailwind": {
|
|
3438
|
+
"config": "tailwind.config.js",
|
|
3439
|
+
"css": "global.css",
|
|
3440
|
+
"baseColor": "neutral",
|
|
3441
|
+
"cssVariables": true
|
|
3442
|
+
},
|
|
3443
|
+
"aliases": {
|
|
3444
|
+
"components": "@/components",
|
|
3445
|
+
"utils": "@/lib/utils",
|
|
3446
|
+
"ui": "@/components/ui",
|
|
3447
|
+
"lib": "@/lib",
|
|
3448
|
+
"hooks": "@/hooks"
|
|
3449
|
+
}
|
|
3450
|
+
}
|
|
3451
|
+
`
|
|
3452
|
+
},
|
|
3453
|
+
// ─── tailwind.config.js (rnr official) ──────────────────────────────
|
|
3555
3454
|
{
|
|
3556
3455
|
path: "tailwind.config.js",
|
|
3557
|
-
content:
|
|
3456
|
+
content: `const { hairlineWidth } = require('nativewind/theme');
|
|
3457
|
+
|
|
3458
|
+
/** @type {import('tailwindcss').Config} */
|
|
3558
3459
|
module.exports = {
|
|
3559
|
-
|
|
3560
|
-
|
|
3561
|
-
|
|
3562
|
-
"./modules/**/*.{js,jsx,ts,tsx}",
|
|
3563
|
-
],
|
|
3564
|
-
presets: [require("nativewind/preset")],
|
|
3460
|
+
darkMode: 'class',
|
|
3461
|
+
content: ['./app/**/*.{ts,tsx}', './components/**/*.{ts,tsx}'],
|
|
3462
|
+
presets: [require('nativewind/preset')],
|
|
3565
3463
|
theme: {
|
|
3566
3464
|
extend: {
|
|
3567
3465
|
colors: {
|
|
3568
|
-
border:
|
|
3569
|
-
input:
|
|
3570
|
-
ring:
|
|
3571
|
-
background:
|
|
3572
|
-
foreground:
|
|
3466
|
+
border: 'hsl(var(--border))',
|
|
3467
|
+
input: 'hsl(var(--input))',
|
|
3468
|
+
ring: 'hsl(var(--ring))',
|
|
3469
|
+
background: 'hsl(var(--background))',
|
|
3470
|
+
foreground: 'hsl(var(--foreground))',
|
|
3573
3471
|
primary: {
|
|
3574
|
-
DEFAULT:
|
|
3575
|
-
foreground:
|
|
3472
|
+
DEFAULT: 'hsl(var(--primary))',
|
|
3473
|
+
foreground: 'hsl(var(--primary-foreground))',
|
|
3576
3474
|
},
|
|
3577
3475
|
secondary: {
|
|
3578
|
-
DEFAULT:
|
|
3579
|
-
foreground:
|
|
3476
|
+
DEFAULT: 'hsl(var(--secondary))',
|
|
3477
|
+
foreground: 'hsl(var(--secondary-foreground))',
|
|
3580
3478
|
},
|
|
3581
3479
|
destructive: {
|
|
3582
|
-
DEFAULT:
|
|
3583
|
-
foreground:
|
|
3480
|
+
DEFAULT: 'hsl(var(--destructive))',
|
|
3481
|
+
foreground: 'hsl(var(--destructive-foreground))',
|
|
3584
3482
|
},
|
|
3585
3483
|
muted: {
|
|
3586
|
-
DEFAULT:
|
|
3587
|
-
foreground:
|
|
3484
|
+
DEFAULT: 'hsl(var(--muted))',
|
|
3485
|
+
foreground: 'hsl(var(--muted-foreground))',
|
|
3588
3486
|
},
|
|
3589
3487
|
accent: {
|
|
3590
|
-
DEFAULT:
|
|
3591
|
-
foreground:
|
|
3488
|
+
DEFAULT: 'hsl(var(--accent))',
|
|
3489
|
+
foreground: 'hsl(var(--accent-foreground))',
|
|
3592
3490
|
},
|
|
3593
3491
|
popover: {
|
|
3594
|
-
DEFAULT:
|
|
3595
|
-
foreground:
|
|
3492
|
+
DEFAULT: 'hsl(var(--popover))',
|
|
3493
|
+
foreground: 'hsl(var(--popover-foreground))',
|
|
3596
3494
|
},
|
|
3597
3495
|
card: {
|
|
3598
|
-
DEFAULT:
|
|
3599
|
-
foreground:
|
|
3496
|
+
DEFAULT: 'hsl(var(--card))',
|
|
3497
|
+
foreground: 'hsl(var(--card-foreground))',
|
|
3600
3498
|
},
|
|
3601
3499
|
},
|
|
3500
|
+
borderRadius: {
|
|
3501
|
+
lg: 'var(--radius)',
|
|
3502
|
+
md: 'calc(var(--radius) - 2px)',
|
|
3503
|
+
sm: 'calc(var(--radius) - 4px)',
|
|
3504
|
+
},
|
|
3505
|
+
borderWidth: {
|
|
3506
|
+
hairline: hairlineWidth(),
|
|
3507
|
+
},
|
|
3508
|
+
keyframes: {
|
|
3509
|
+
'accordion-down': {
|
|
3510
|
+
from: { height: '0' },
|
|
3511
|
+
to: { height: 'var(--radix-accordion-content-height)' },
|
|
3512
|
+
},
|
|
3513
|
+
'accordion-up': {
|
|
3514
|
+
from: { height: 'var(--radix-accordion-content-height)' },
|
|
3515
|
+
to: { height: '0' },
|
|
3516
|
+
},
|
|
3517
|
+
},
|
|
3518
|
+
animation: {
|
|
3519
|
+
'accordion-down': 'accordion-down 0.2s ease-out',
|
|
3520
|
+
'accordion-up': 'accordion-up 0.2s ease-out',
|
|
3521
|
+
},
|
|
3602
3522
|
},
|
|
3603
3523
|
},
|
|
3604
|
-
|
|
3524
|
+
future: {
|
|
3525
|
+
hoverOnlyWhenSupported: true,
|
|
3526
|
+
},
|
|
3527
|
+
plugins: [require('tailwindcss-animate')],
|
|
3605
3528
|
};
|
|
3606
3529
|
`
|
|
3607
3530
|
},
|
|
3608
|
-
// ─── metro.config.js
|
|
3531
|
+
// ─── metro.config.js (rnr official: inlineRem: 16) ──────────────────
|
|
3609
3532
|
{
|
|
3610
3533
|
path: "metro.config.js",
|
|
3611
3534
|
content: `const { getDefaultConfig } = require("expo/metro-config");
|
|
@@ -3613,7 +3536,7 @@ const { withNativeWind } = require("nativewind/metro");
|
|
|
3613
3536
|
|
|
3614
3537
|
const config = getDefaultConfig(__dirname);
|
|
3615
3538
|
|
|
3616
|
-
module.exports = withNativeWind(config, { input: "./global.css" });
|
|
3539
|
+
module.exports = withNativeWind(config, { input: "./global.css", inlineRem: 16 });
|
|
3617
3540
|
`
|
|
3618
3541
|
},
|
|
3619
3542
|
// ─── babel.config.js ─────────────────────────────────────────────────
|
|
@@ -3631,7 +3554,7 @@ module.exports = withNativeWind(config, { input: "./global.css" });
|
|
|
3631
3554
|
};
|
|
3632
3555
|
`
|
|
3633
3556
|
},
|
|
3634
|
-
// ─── global.css (
|
|
3557
|
+
// ─── global.css (rnr official CSS variables) ─────────────────────────
|
|
3635
3558
|
{
|
|
3636
3559
|
path: "global.css",
|
|
3637
3560
|
content: `@tailwind base;
|
|
@@ -3641,46 +3564,55 @@ module.exports = withNativeWind(config, { input: "./global.css" });
|
|
|
3641
3564
|
@layer base {
|
|
3642
3565
|
:root {
|
|
3643
3566
|
--background: 0 0% 100%;
|
|
3644
|
-
--foreground:
|
|
3567
|
+
--foreground: 0 0% 3.9%;
|
|
3645
3568
|
--card: 0 0% 100%;
|
|
3646
|
-
--card-foreground:
|
|
3569
|
+
--card-foreground: 0 0% 3.9%;
|
|
3647
3570
|
--popover: 0 0% 100%;
|
|
3648
|
-
--popover-foreground:
|
|
3649
|
-
--primary:
|
|
3571
|
+
--popover-foreground: 0 0% 3.9%;
|
|
3572
|
+
--primary: 0 0% 9%;
|
|
3650
3573
|
--primary-foreground: 0 0% 98%;
|
|
3651
|
-
--secondary:
|
|
3652
|
-
--secondary-foreground:
|
|
3653
|
-
--muted:
|
|
3654
|
-
--muted-foreground:
|
|
3655
|
-
--accent:
|
|
3656
|
-
--accent-foreground:
|
|
3574
|
+
--secondary: 0 0% 96.1%;
|
|
3575
|
+
--secondary-foreground: 0 0% 9%;
|
|
3576
|
+
--muted: 0 0% 96.1%;
|
|
3577
|
+
--muted-foreground: 0 0% 45.1%;
|
|
3578
|
+
--accent: 0 0% 96.1%;
|
|
3579
|
+
--accent-foreground: 0 0% 9%;
|
|
3657
3580
|
--destructive: 0 84.2% 60.2%;
|
|
3658
|
-
--
|
|
3659
|
-
--
|
|
3660
|
-
--
|
|
3661
|
-
--
|
|
3581
|
+
--border: 0 0% 89.8%;
|
|
3582
|
+
--input: 0 0% 89.8%;
|
|
3583
|
+
--ring: 0 0% 63%;
|
|
3584
|
+
--radius: 0.625rem;
|
|
3585
|
+
--chart-1: 12 76% 61%;
|
|
3586
|
+
--chart-2: 173 58% 39%;
|
|
3587
|
+
--chart-3: 197 37% 24%;
|
|
3588
|
+
--chart-4: 43 74% 66%;
|
|
3589
|
+
--chart-5: 27 87% 67%;
|
|
3662
3590
|
}
|
|
3663
3591
|
|
|
3664
|
-
.dark {
|
|
3665
|
-
--background:
|
|
3592
|
+
.dark:root {
|
|
3593
|
+
--background: 0 0% 3.9%;
|
|
3666
3594
|
--foreground: 0 0% 98%;
|
|
3667
|
-
--card:
|
|
3595
|
+
--card: 0 0% 3.9%;
|
|
3668
3596
|
--card-foreground: 0 0% 98%;
|
|
3669
|
-
--popover:
|
|
3597
|
+
--popover: 0 0% 3.9%;
|
|
3670
3598
|
--popover-foreground: 0 0% 98%;
|
|
3671
3599
|
--primary: 0 0% 98%;
|
|
3672
|
-
--primary-foreground:
|
|
3673
|
-
--secondary:
|
|
3600
|
+
--primary-foreground: 0 0% 9%;
|
|
3601
|
+
--secondary: 0 0% 14.9%;
|
|
3674
3602
|
--secondary-foreground: 0 0% 98%;
|
|
3675
|
-
--muted:
|
|
3676
|
-
--muted-foreground:
|
|
3677
|
-
--accent:
|
|
3603
|
+
--muted: 0 0% 14.9%;
|
|
3604
|
+
--muted-foreground: 0 0% 63.9%;
|
|
3605
|
+
--accent: 0 0% 14.9%;
|
|
3678
3606
|
--accent-foreground: 0 0% 98%;
|
|
3679
|
-
--destructive: 0
|
|
3680
|
-
--
|
|
3681
|
-
--
|
|
3682
|
-
--
|
|
3683
|
-
--
|
|
3607
|
+
--destructive: 0 70.9% 59.4%;
|
|
3608
|
+
--border: 0 0% 14.9%;
|
|
3609
|
+
--input: 0 0% 14.9%;
|
|
3610
|
+
--ring: 300 0% 45%;
|
|
3611
|
+
--chart-1: 220 70% 50%;
|
|
3612
|
+
--chart-2: 160 60% 45%;
|
|
3613
|
+
--chart-3: 30 80% 55%;
|
|
3614
|
+
--chart-4: 280 65% 60%;
|
|
3615
|
+
--chart-5: 340 75% 55%;
|
|
3684
3616
|
}
|
|
3685
3617
|
}
|
|
3686
3618
|
`
|
|
@@ -3738,14 +3670,15 @@ function generateLoginTabsTemplates(projectName) {
|
|
|
3738
3670
|
{
|
|
3739
3671
|
path: "app/_layout.tsx",
|
|
3740
3672
|
content: lines(
|
|
3673
|
+
'import "../global.css";',
|
|
3741
3674
|
'import { DarkTheme, DefaultTheme, ThemeProvider } from "@react-navigation/native";',
|
|
3742
3675
|
'import { useFonts } from "expo-font";',
|
|
3743
3676
|
'import { Stack } from "expo-router";',
|
|
3744
3677
|
'import * as SplashScreen from "expo-splash-screen";',
|
|
3745
3678
|
'import { useEffect } from "react";',
|
|
3746
3679
|
'import { useColorScheme } from "react-native";',
|
|
3747
|
-
"",
|
|
3748
|
-
'import {
|
|
3680
|
+
'import { PortalHost } from "@rn-primitives/portal";',
|
|
3681
|
+
'import { NAV_THEME } from "@/lib/theme";',
|
|
3749
3682
|
"",
|
|
3750
3683
|
"SplashScreen.preventAutoHideAsync();",
|
|
3751
3684
|
"",
|
|
@@ -3766,12 +3699,14 @@ function generateLoginTabsTemplates(projectName) {
|
|
|
3766
3699
|
" }",
|
|
3767
3700
|
"",
|
|
3768
3701
|
" return (",
|
|
3769
|
-
' <ThemeProvider value={colorScheme === "dark" ?
|
|
3702
|
+
' <ThemeProvider value={colorScheme === "dark" ? NAV_THEME.dark : NAV_THEME.light}>',
|
|
3703
|
+
' <StatusBar style={colorScheme === "dark" ? "light" : "dark"} />',
|
|
3770
3704
|
" <Stack>",
|
|
3771
3705
|
' <Stack.Screen name="login" options={{ headerShown: false }} />',
|
|
3772
3706
|
' <Stack.Screen name="(tabs)" options={{ headerShown: false }} />',
|
|
3773
3707
|
' <Stack.Screen name="+not-found" />',
|
|
3774
3708
|
" </Stack>",
|
|
3709
|
+
" <PortalHost />",
|
|
3775
3710
|
" </ThemeProvider>",
|
|
3776
3711
|
" );",
|
|
3777
3712
|
"}",
|
|
@@ -3802,19 +3737,10 @@ function generateLoginTabsTemplates(projectName) {
|
|
|
3802
3737
|
'import { Tabs } from "expo-router";',
|
|
3803
3738
|
'import { Platform } from "react-native";',
|
|
3804
3739
|
"",
|
|
3805
|
-
'import { Colors } from "@/constants/Colors";',
|
|
3806
|
-
'import { useColorScheme } from "@/hooks/useColorScheme";',
|
|
3807
|
-
"",
|
|
3808
3740
|
"export default function TabLayout() {",
|
|
3809
|
-
" const colorScheme = useColorScheme();",
|
|
3810
|
-
"",
|
|
3811
3741
|
" return (",
|
|
3812
3742
|
" <Tabs",
|
|
3813
3743
|
" screenOptions={{",
|
|
3814
|
-
' tabBarActiveTintColor: Colors[colorScheme ?? "light"].tint,',
|
|
3815
|
-
" headerStyle: {",
|
|
3816
|
-
' backgroundColor: Colors[colorScheme ?? "light"].background,',
|
|
3817
|
-
" },",
|
|
3818
3744
|
" headerShadowVisible: false,",
|
|
3819
3745
|
" tabBarStyle: Platform.select({",
|
|
3820
3746
|
" ios: {",
|
|
@@ -3825,16 +3751,16 @@ function generateLoginTabsTemplates(projectName) {
|
|
|
3825
3751
|
" }}",
|
|
3826
3752
|
" >",
|
|
3827
3753
|
" <Tabs.Screen",
|
|
3828
|
-
' name="
|
|
3754
|
+
' name="index"',
|
|
3829
3755
|
" options={{",
|
|
3830
3756
|
' title: "Home",',
|
|
3831
3757
|
" tabBarIcon: () => null,",
|
|
3832
3758
|
" }}",
|
|
3833
3759
|
" />",
|
|
3834
3760
|
" <Tabs.Screen",
|
|
3835
|
-
' name="
|
|
3761
|
+
' name="explore"',
|
|
3836
3762
|
" options={{",
|
|
3837
|
-
' title: "
|
|
3763
|
+
' title: "Explore",',
|
|
3838
3764
|
" tabBarIcon: () => null,",
|
|
3839
3765
|
" }}",
|
|
3840
3766
|
" />",
|
|
@@ -3851,9 +3777,9 @@ function generateLoginTabsTemplates(projectName) {
|
|
|
3851
3777
|
""
|
|
3852
3778
|
)
|
|
3853
3779
|
},
|
|
3854
|
-
// ─── app/(tabs)/
|
|
3780
|
+
// ─── app/(tabs)/index.tsx ──────────────────────────────────────────
|
|
3855
3781
|
{
|
|
3856
|
-
path: "app/(tabs)/
|
|
3782
|
+
path: "app/(tabs)/index.tsx",
|
|
3857
3783
|
content: lines(
|
|
3858
3784
|
'import { Button } from "@/components/ui/button";',
|
|
3859
3785
|
"import {",
|
|
@@ -3934,9 +3860,9 @@ function generateLoginTabsTemplates(projectName) {
|
|
|
3934
3860
|
""
|
|
3935
3861
|
)
|
|
3936
3862
|
},
|
|
3937
|
-
// ─── app/(tabs)/
|
|
3863
|
+
// ─── app/(tabs)/explore.tsx ────────────────────────────────────────
|
|
3938
3864
|
{
|
|
3939
|
-
path: "app/(tabs)/
|
|
3865
|
+
path: "app/(tabs)/explore.tsx",
|
|
3940
3866
|
content: lines(
|
|
3941
3867
|
'import { Text } from "@/components/ui/text";',
|
|
3942
3868
|
'import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";',
|
|
@@ -3948,10 +3874,10 @@ function generateLoginTabsTemplates(projectName) {
|
|
|
3948
3874
|
" description: `Description for item ${i + 1}`,",
|
|
3949
3875
|
"}));",
|
|
3950
3876
|
"",
|
|
3951
|
-
"export default function
|
|
3877
|
+
"export default function ExploreScreen() {",
|
|
3952
3878
|
" return (",
|
|
3953
3879
|
' <ScrollView className="flex-1 p-4">',
|
|
3954
|
-
' <Text variant="h3" className="mb-4">
|
|
3880
|
+
' <Text variant="h3" className="mb-4">Explore</Text>',
|
|
3955
3881
|
' <View className="gap-3">',
|
|
3956
3882
|
" {ITEMS.map((item) => (",
|
|
3957
3883
|
" <Card key={item.id}>",
|
|
@@ -4011,7 +3937,7 @@ function generateLoginTabsTemplates(projectName) {
|
|
|
4011
3937
|
""
|
|
4012
3938
|
)
|
|
4013
3939
|
},
|
|
4014
|
-
// ───
|
|
3940
|
+
// ─── components/SignInForm.tsx ────────────────────────────────────
|
|
4015
3941
|
{
|
|
4016
3942
|
path: "components/SignInForm.tsx",
|
|
4017
3943
|
content: lines(
|
|
@@ -4040,7 +3966,7 @@ function generateLoginTabsTemplates(projectName) {
|
|
|
4040
3966
|
"",
|
|
4041
3967
|
" function onSubmit() {",
|
|
4042
3968
|
" // TODO: Submit form and navigate to protected screen if successful",
|
|
4043
|
-
' router.replace("/(tabs)
|
|
3969
|
+
' router.replace("/(tabs)");',
|
|
4044
3970
|
" }",
|
|
4045
3971
|
"",
|
|
4046
3972
|
" return (",
|
|
@@ -4200,6 +4126,7 @@ function generateBasePackageJson(projectName) {
|
|
|
4200
4126
|
// ─── Styling ──────────────────────────────────────────────────
|
|
4201
4127
|
nativewind: "^4.1.0",
|
|
4202
4128
|
tailwindcss: "^3.4.0",
|
|
4129
|
+
"tailwindcss-animate": "^1.0.7",
|
|
4203
4130
|
"react-native-svg": "15.12.1",
|
|
4204
4131
|
// ─── Network ─────────────────────────────────────────────────
|
|
4205
4132
|
"@tanstack/react-query": "^5.60.0",
|
|
@@ -4262,7 +4189,7 @@ function generateBasePackageJson(projectName) {
|
|
|
4262
4189
|
|
|
4263
4190
|
// src/index.ts
|
|
4264
4191
|
var import_execa = require("execa");
|
|
4265
|
-
var CLI_VERSION = "1.
|
|
4192
|
+
var CLI_VERSION = "1.7.0";
|
|
4266
4193
|
var CONFIG_FILE = ".expo-bbase.json";
|
|
4267
4194
|
async function run() {
|
|
4268
4195
|
const program = new import_commander.Command();
|
|
@@ -4309,12 +4236,12 @@ async function createProject(projectName) {
|
|
|
4309
4236
|
message: "Choose a UI template",
|
|
4310
4237
|
choices: [
|
|
4311
4238
|
{
|
|
4312
|
-
title: `${import_chalk.default.bold("Login + Tabs")} \u2014 Login page,
|
|
4239
|
+
title: `${import_chalk.default.bold("Login + Tabs")} \u2014 Login page, Index/Explore/Mine tabs with rnr components`,
|
|
4313
4240
|
value: "login-tabs",
|
|
4314
4241
|
description: "Pre-built login form, 3-tab layout with Button & AlertDialog demos"
|
|
4315
4242
|
},
|
|
4316
4243
|
{
|
|
4317
|
-
title: `${import_chalk.default.bold("Default")} \u2014 Blank tabs (
|
|
4244
|
+
title: `${import_chalk.default.bold("Default")} \u2014 Blank tabs (Index + Explore)`,
|
|
4318
4245
|
value: "default",
|
|
4319
4246
|
description: "Minimal starter with basic tab navigation"
|
|
4320
4247
|
}
|