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 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 { Colors } from "@/constants/Colors";
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" ? DarkTheme : DefaultTheme}>
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 { Image, StyleSheet, Platform } from "react-native";
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
- <ThemedView style={styles.container}>
3246
- <ThemedView style={styles.titleContainer}>
3247
- <ThemedText type="title">${projectName}</ThemedText>
3248
- <HelloWave />
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 { StyleSheet, Image, Platform } from "react-native";
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
- <ThemedView style={styles.container}>
3302
- <ThemedText type="title">Explore</ThemedText>
3303
- <ThemedText style={styles.subtitle}>
3304
- This screen shows what you can do with this scaffolded project.
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 { StyleSheet } from "react-native";
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
- <ThemedView style={styles.container}>
3337
- <ThemedText type="title">This screen doesn't exist.</ThemedText>
3338
- <Link href="/" style={styles.link}>
3339
- <ThemedText type="link">Go to home screen!</ThemedText>
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
- </ThemedView>
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
- // ─── src/components/Themed.tsx ───────────────────────────────────────
3265
+ // ─── lib/utils.ts (rnr official cn helper) ───────────────────────────
3361
3266
  {
3362
- path: "components/Themed.tsx",
3363
- content: `import { Text, type TextProps, View, type ViewProps } from "react-native";
3364
- import { useColorScheme } from "@/hooks/useColorScheme";
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
- return <View style={[{ backgroundColor }, style]} {...rest} />;
3271
+ export function cn(...inputs: ClassValue[]) {
3272
+ return twMerge(clsx(inputs));
3398
3273
  }
3399
3274
  `
3400
3275
  },
3401
- // ─── src/components/HelloWave.tsx ────────────────────────────────────
3276
+ // ─── lib/theme.ts (rnr official theme) ───────────────────────────────
3402
3277
  {
3403
- path: "components/HelloWave.tsx",
3404
- content: `import { useEffect } from "react";
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
- useEffect(() => {
3412
- Animated.loop(
3413
- Animated.sequence([
3414
- Animated.timing(rotationAnim, {
3415
- toValue: 1,
3416
- duration: 150,
3417
- easing: Easing.linear,
3418
- useNativeDriver: true,
3419
- }),
3420
- Animated.timing(rotationAnim, {
3421
- toValue: 0,
3422
- duration: 150,
3423
- easing: Easing.linear,
3424
- useNativeDriver: true,
3425
- }),
3426
- ])
3427
- ).start();
3428
- }, [rotationAnim]);
3429
-
3430
- return (
3431
- <Animated.View
3432
- style={{
3433
- transform: [
3434
- {
3435
- rotate: rotationAnim.interpolate({
3436
- inputRange: [0, 1],
3437
- outputRange: ["0deg", "14deg"],
3438
- }),
3439
- },
3440
- ],
3441
- }}
3442
- >
3443
- <ThemedText style={{ fontSize: 28 }}>\u{1F44B}</ThemedText>
3444
- </Animated.View>
3445
- );
3446
- }
3447
- `
3448
- },
3449
- // ─── src/hooks/useColorScheme.ts ─────────────────────────────────────
3450
- {
3451
- path: "hooks/useColorScheme.ts",
3452
- content: `import { useColorScheme as useRNColorScheme } from "react-native";
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
- text: "#11181C",
3473
- background: "#fff",
3474
- tint: "#0a7ea4",
3475
- tabIconDefault: "#687076",
3476
- tabIconSelected: "#0a7ea4",
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
- text: "#ECEDEE",
3480
- background: "#151718",
3481
- tint: "#fff",
3482
- tabIconDefault: "#9BA1A6",
3483
- tabIconSelected: "#fff",
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
- // ─── src/types/index.ts ─────────────────────────────────────────────
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
- // ─── tailwind.config.js ──────────────────────────────────────────────
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: `/** @type {import('tailwindcss').Config} */
3456
+ content: `const { hairlineWidth } = require('nativewind/theme');
3457
+
3458
+ /** @type {import('tailwindcss').Config} */
3558
3459
  module.exports = {
3559
- content: [
3560
- "./app/**/*.{js,jsx,ts,tsx}",
3561
- "./components/**/*.{js,jsx,ts,tsx}",
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: "hsl(var(--border))",
3569
- input: "hsl(var(--input))",
3570
- ring: "hsl(var(--ring))",
3571
- background: "hsl(var(--background))",
3572
- foreground: "hsl(var(--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: "hsl(var(--primary))",
3575
- foreground: "hsl(var(--primary-foreground))",
3472
+ DEFAULT: 'hsl(var(--primary))',
3473
+ foreground: 'hsl(var(--primary-foreground))',
3576
3474
  },
3577
3475
  secondary: {
3578
- DEFAULT: "hsl(var(--secondary))",
3579
- foreground: "hsl(var(--secondary-foreground))",
3476
+ DEFAULT: 'hsl(var(--secondary))',
3477
+ foreground: 'hsl(var(--secondary-foreground))',
3580
3478
  },
3581
3479
  destructive: {
3582
- DEFAULT: "hsl(var(--destructive))",
3583
- foreground: "hsl(var(--destructive-foreground))",
3480
+ DEFAULT: 'hsl(var(--destructive))',
3481
+ foreground: 'hsl(var(--destructive-foreground))',
3584
3482
  },
3585
3483
  muted: {
3586
- DEFAULT: "hsl(var(--muted))",
3587
- foreground: "hsl(var(--muted-foreground))",
3484
+ DEFAULT: 'hsl(var(--muted))',
3485
+ foreground: 'hsl(var(--muted-foreground))',
3588
3486
  },
3589
3487
  accent: {
3590
- DEFAULT: "hsl(var(--accent))",
3591
- foreground: "hsl(var(--accent-foreground))",
3488
+ DEFAULT: 'hsl(var(--accent))',
3489
+ foreground: 'hsl(var(--accent-foreground))',
3592
3490
  },
3593
3491
  popover: {
3594
- DEFAULT: "hsl(var(--popover))",
3595
- foreground: "hsl(var(--popover-foreground))",
3492
+ DEFAULT: 'hsl(var(--popover))',
3493
+ foreground: 'hsl(var(--popover-foreground))',
3596
3494
  },
3597
3495
  card: {
3598
- DEFAULT: "hsl(var(--card))",
3599
- foreground: "hsl(var(--card-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
- plugins: [],
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 (NativeWind CSS variables for rnr components) ─────────
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: 240 10% 3.9%;
3567
+ --foreground: 0 0% 3.9%;
3645
3568
  --card: 0 0% 100%;
3646
- --card-foreground: 240 10% 3.9%;
3569
+ --card-foreground: 0 0% 3.9%;
3647
3570
  --popover: 0 0% 100%;
3648
- --popover-foreground: 240 10% 3.9%;
3649
- --primary: 240 5.9% 10%;
3571
+ --popover-foreground: 0 0% 3.9%;
3572
+ --primary: 0 0% 9%;
3650
3573
  --primary-foreground: 0 0% 98%;
3651
- --secondary: 240 4.8% 95.9%;
3652
- --secondary-foreground: 240 5.9% 10%;
3653
- --muted: 240 4.8% 95.9%;
3654
- --muted-foreground: 240 3.8% 46.1%;
3655
- --accent: 240 4.8% 95.9%;
3656
- --accent-foreground: 240 5.9% 10%;
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
- --destructive-foreground: 0 0% 98%;
3659
- --border: 240 5.9% 90%;
3660
- --input: 240 5.9% 90%;
3661
- --ring: 240 5.9% 10%;
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: 240 10% 3.9%;
3592
+ .dark:root {
3593
+ --background: 0 0% 3.9%;
3666
3594
  --foreground: 0 0% 98%;
3667
- --card: 240 10% 3.9%;
3595
+ --card: 0 0% 3.9%;
3668
3596
  --card-foreground: 0 0% 98%;
3669
- --popover: 240 10% 3.9%;
3597
+ --popover: 0 0% 3.9%;
3670
3598
  --popover-foreground: 0 0% 98%;
3671
3599
  --primary: 0 0% 98%;
3672
- --primary-foreground: 240 5.9% 10%;
3673
- --secondary: 240 3.7% 15.9%;
3600
+ --primary-foreground: 0 0% 9%;
3601
+ --secondary: 0 0% 14.9%;
3674
3602
  --secondary-foreground: 0 0% 98%;
3675
- --muted: 240 3.7% 15.9%;
3676
- --muted-foreground: 240 5% 64.9%;
3677
- --accent: 240 3.7% 15.9%;
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 62.8% 30.6%;
3680
- --destructive-foreground: 0 0% 98%;
3681
- --border: 240 3.7% 15.9%;
3682
- --input: 240 3.7% 15.9%;
3683
- --ring: 240 4.9% 83.9%;
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 { Colors } from "@/constants/Colors";',
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" ? DarkTheme : DefaultTheme}>',
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="home"',
3754
+ ' name="index"',
3829
3755
  " options={{",
3830
3756
  ' title: "Home",',
3831
3757
  " tabBarIcon: () => null,",
3832
3758
  " }}",
3833
3759
  " />",
3834
3760
  " <Tabs.Screen",
3835
- ' name="list"',
3761
+ ' name="explore"',
3836
3762
  " options={{",
3837
- ' title: "List",',
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)/home.tsx ────────────────────────────────────────────
3780
+ // ─── app/(tabs)/index.tsx ──────────────────────────────────────────
3855
3781
  {
3856
- path: "app/(tabs)/home.tsx",
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)/list.tsx ────────────────────────────────────────────
3863
+ // ─── app/(tabs)/explore.tsx ────────────────────────────────────────
3938
3864
  {
3939
- path: "app/(tabs)/list.tsx",
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 ListScreen() {",
3877
+ "export default function ExploreScreen() {",
3952
3878
  " return (",
3953
3879
  ' <ScrollView className="flex-1 p-4">',
3954
- ' <Text variant="h3" className="mb-4">List</Text>',
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
- // ─── src/components/SignInForm.tsx ───────────────────────────────────
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)/home");',
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.6.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, Home/List/Mine tabs with rnr components`,
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 (Home + Explore)`,
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
  }