mirror of
https://github.com/FranP-code/create-better-t-stack.git
synced 2025-10-12 23:52:15 +00:00
feat(cli): upgrade to expo 54 (#574)
This commit is contained in:
@@ -1,2 +0,0 @@
|
||||
// @ts-ignore
|
||||
/// <reference types="nativewind/types" />
|
||||
@@ -1,46 +0,0 @@
|
||||
{
|
||||
"expo": {
|
||||
"name": "my-better-t-app",
|
||||
"slug": "my-better-t-app",
|
||||
"version": "1.0.0",
|
||||
"scheme": "my-better-t-app",
|
||||
"web": {
|
||||
"bundler": "metro",
|
||||
"output": "static",
|
||||
"favicon": "./assets/favicon.png"
|
||||
},
|
||||
"plugins": [
|
||||
"expo-router",
|
||||
"expo-secure-store",
|
||||
"expo-web-browser"
|
||||
],
|
||||
"experiments": {
|
||||
"typedRoutes": true,
|
||||
"tsconfigPaths": true
|
||||
},
|
||||
"newArchEnabled": true,
|
||||
"orientation": "portrait",
|
||||
"icon": "./assets/icon.png",
|
||||
"userInterfaceStyle": "light",
|
||||
"splash": {
|
||||
"image": "./assets/splash.png",
|
||||
"resizeMode": "contain",
|
||||
"backgroundColor": "#ffffff"
|
||||
},
|
||||
"assetBundlePatterns": [
|
||||
"**/*"
|
||||
],
|
||||
"ios": {
|
||||
"supportsTablet": true,
|
||||
"bundleIdentifier": "com.amanvarshney01.mybettertapp"
|
||||
},
|
||||
"android": {
|
||||
"adaptiveIcon": {
|
||||
"foregroundImage": "./assets/adaptive-icon.png",
|
||||
"backgroundColor": "#ffffff"
|
||||
},
|
||||
"package": "com.amanvarshney01.mybettertapp",
|
||||
"edgeToEdgeEnabled": true
|
||||
}
|
||||
}
|
||||
}
|
||||
49
apps/cli/templates/frontend/native/nativewind/app.json.hbs
Normal file
49
apps/cli/templates/frontend/native/nativewind/app.json.hbs
Normal file
@@ -0,0 +1,49 @@
|
||||
{
|
||||
"expo": {
|
||||
"name": "{{projectName}}",
|
||||
"slug": "{{projectName}}",
|
||||
"version": "1.0.0",
|
||||
"orientation": "portrait",
|
||||
"icon": "./assets/images/icon.png",
|
||||
"scheme": "mybettertapp",
|
||||
"userInterfaceStyle": "automatic",
|
||||
"newArchEnabled": true,
|
||||
"ios": {
|
||||
"supportsTablet": true
|
||||
},
|
||||
"android": {
|
||||
"adaptiveIcon": {
|
||||
"backgroundColor": "#E6F4FE",
|
||||
"foregroundImage": "./assets/images/android-icon-foreground.png",
|
||||
"backgroundImage": "./assets/images/android-icon-background.png",
|
||||
"monochromeImage": "./assets/images/android-icon-monochrome.png"
|
||||
},
|
||||
"edgeToEdgeEnabled": true,
|
||||
"predictiveBackGestureEnabled": false,
|
||||
"package": "com.anonymous.mybettertapp"
|
||||
},
|
||||
"web": {
|
||||
"output": "static",
|
||||
"favicon": "./assets/images/favicon.png"
|
||||
},
|
||||
"plugins": [
|
||||
"expo-router",
|
||||
[
|
||||
"expo-splash-screen",
|
||||
{
|
||||
"image": "./assets/images/splash-icon.png",
|
||||
"imageWidth": 200,
|
||||
"resizeMode": "contain",
|
||||
"backgroundColor": "#ffffff",
|
||||
"dark": {
|
||||
"backgroundColor": "#000000"
|
||||
}
|
||||
}
|
||||
]
|
||||
],
|
||||
"experiments": {
|
||||
"typedRoutes": true,
|
||||
"reactCompiler": true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,7 @@ export default function TabLayout() {
|
||||
|
||||
return (
|
||||
<Tabs
|
||||
screenOptions={{
|
||||
screenOptions=\{{
|
||||
headerShown: false,
|
||||
tabBarActiveTintColor: isDarkColorScheme
|
||||
? "hsl(217.2 91.2% 59.8%)"
|
||||
@@ -27,14 +27,14 @@ export default function TabLayout() {
|
||||
>
|
||||
<Tabs.Screen
|
||||
name="index"
|
||||
options={{
|
||||
options=\{{
|
||||
title: "Home",
|
||||
tabBarIcon: ({ color }) => <TabBarIcon name="home" color={color} />,
|
||||
}}
|
||||
/>
|
||||
<Tabs.Screen
|
||||
name="two"
|
||||
options={{
|
||||
options=\{{
|
||||
title: "Explore",
|
||||
tabBarIcon: ({ color }) => (
|
||||
<TabBarIcon name="compass" color={color} />
|
||||
@@ -1,47 +0,0 @@
|
||||
import { ScrollViewStyleReset } from 'expo-router/html';
|
||||
import { ReactNode } from 'react';
|
||||
|
||||
// This file is web-only and used to configure the root HTML for every
|
||||
// web page during static rendering.
|
||||
// The contents of this function only run in Node.js environments and
|
||||
// do not have access to the DOM or browser APIs.
|
||||
export default function Root({ children }: { children: ReactNode }) {
|
||||
return (
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charSet="utf-8" />
|
||||
<meta content="IE=edge" httpEquiv="X-UA-Compatible" />
|
||||
|
||||
{/*
|
||||
This viewport disables scaling which makes the mobile website act more like a native app.
|
||||
However this does reduce built-in accessibility. If you want to enable scaling, use this instead:
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
|
||||
*/}
|
||||
<meta
|
||||
content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1.00001,viewport-fit=cover"
|
||||
name="viewport"
|
||||
/>
|
||||
{/*
|
||||
Disable body scrolling on web. This makes ScrollView components work closer to how they do on native.
|
||||
However, body scrolling is often nice to have for mobile web. If you want to enable it, remove this line.
|
||||
*/}
|
||||
<ScrollViewStyleReset />
|
||||
|
||||
{/* Using raw CSS styles as an escape-hatch to ensure the background color never flickers in dark-mode. */}
|
||||
<style dangerouslySetInnerHTML={{ __html: responsiveBackground }} />
|
||||
{/* Add any additional <head> elements that you want globally available on web... */}
|
||||
</head>
|
||||
<body>{children}</body>
|
||||
</html>
|
||||
);
|
||||
}
|
||||
|
||||
const responsiveBackground = `
|
||||
body {
|
||||
background-color: #fff;
|
||||
}
|
||||
@media (prefers-color-scheme: dark) {
|
||||
body {
|
||||
background-color: #000;
|
||||
}
|
||||
}`;
|
||||
@@ -5,7 +5,7 @@ import { Text, View } from "react-native";
|
||||
export default function NotFoundScreen() {
|
||||
return (
|
||||
<>
|
||||
<Stack.Screen options={{ title: "Oops!" }} />
|
||||
<Stack.Screen options=\{{ title: "Oops!" }} />
|
||||
<Container>
|
||||
<View className="flex-1 justify-center items-center p-6">
|
||||
<View className="items-center">
|
||||
@@ -1,11 +0,0 @@
|
||||
module.exports = function (api) {
|
||||
api.cache(true);
|
||||
const plugins = [];
|
||||
|
||||
plugins.push('react-native-reanimated/plugin');
|
||||
|
||||
return {
|
||||
presets: [['babel-preset-expo', { jsxImportSource: 'nativewind' }], 'nativewind/babel'],
|
||||
plugins,
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,14 @@
|
||||
module.exports = (api) => {
|
||||
api.cache(true);
|
||||
const plugins = [];
|
||||
|
||||
plugins.push("react-native-worklets/plugin");
|
||||
|
||||
return {
|
||||
presets: [
|
||||
["babel-preset-expo", { jsxImportSource: "nativewind" }],
|
||||
"nativewind/babel",
|
||||
],
|
||||
plugins,
|
||||
};
|
||||
};
|
||||
@@ -1,5 +1,5 @@
|
||||
import React from "react";
|
||||
import { SafeAreaView } from "react-native";
|
||||
import { SafeAreaView } from "react-native-safe-area-context";
|
||||
|
||||
export const Container = ({ children }: { children: React.ReactNode }) => {
|
||||
return (
|
||||
@@ -16,7 +16,7 @@ export const HeaderButton = forwardRef<
|
||||
name="info-circle"
|
||||
size={20}
|
||||
className="text-secondary-foreground"
|
||||
style={{
|
||||
style=\{{
|
||||
opacity: pressed ? 0.7 : 1,
|
||||
}}
|
||||
/>
|
||||
@@ -4,5 +4,5 @@ export const TabBarIcon = (props: {
|
||||
name: React.ComponentProps<typeof FontAwesome>["name"];
|
||||
color: string;
|
||||
}) => {
|
||||
return <FontAwesome size={24} style={{ marginBottom: -3 }} {...props} />;
|
||||
return <FontAwesome size={24} style=\{{ marginBottom: -3 }} {...props} />;
|
||||
};
|
||||
@@ -10,39 +10,41 @@
|
||||
"web": "expo start --web"
|
||||
},
|
||||
"dependencies": {
|
||||
"@expo/vector-icons": "^14.0.4",
|
||||
"@expo/vector-icons": "^15.0.2",
|
||||
"@react-navigation/bottom-tabs": "^7.2.0",
|
||||
"@react-navigation/drawer": "^7.1.1",
|
||||
"@react-navigation/native": "^7.0.14",
|
||||
"@tanstack/react-form": "^1.0.5",
|
||||
"@tanstack/react-query": "^5.69.2",
|
||||
"@tanstack/react-query": "^5.85.5",
|
||||
{{#if (includes examples "ai")}}
|
||||
"@stardazed/streams-text-encoding": "^1.0.2",
|
||||
"@ungap/structured-clone": "^1.3.0",
|
||||
{{/if}}
|
||||
"expo": "^53.0.4",
|
||||
"expo-constants": "~17.1.4",
|
||||
"expo-crypto": "~14.1.5",
|
||||
"expo-linking": "~7.1.4",
|
||||
"expo-navigation-bar": "~4.2.3",
|
||||
"expo-router": "~5.0.3",
|
||||
"expo-secure-store": "~14.2.3",
|
||||
"expo-status-bar": "~2.2.3",
|
||||
"expo-system-ui": "~5.0.6",
|
||||
"expo-web-browser": "~14.1.6",
|
||||
"expo": "^54.0.1",
|
||||
"expo-constants": "~18.0.8",
|
||||
"expo-crypto": "~15.0.6",
|
||||
"expo-linking": "~8.0.7",
|
||||
"expo-navigation-bar": "~5.0.8",
|
||||
"expo-router": "~6.0.0",
|
||||
"expo-secure-store": "~15.0.6",
|
||||
"expo-splash-screen": "~31.0.8",
|
||||
"expo-status-bar": "~3.0.7",
|
||||
"expo-system-ui": "~6.0.7",
|
||||
"expo-web-browser": "~15.0.6",
|
||||
"nativewind": "^4.1.23",
|
||||
"react": "19.0.0",
|
||||
"react-dom": "19.0.0",
|
||||
"react-native": "0.79.1",
|
||||
"react-native-gesture-handler": "~2.24.0",
|
||||
"react-native-reanimated": "~3.17.4",
|
||||
"react-native-safe-area-context": "5.3.0",
|
||||
"react-native-screens": "~4.10.0",
|
||||
"react-native-web": "^0.20.0"
|
||||
"react": "19.1.0",
|
||||
"react-dom": "19.1.0",
|
||||
"react-native": "0.81.4",
|
||||
"react-native-gesture-handler": "~2.28.0",
|
||||
"react-native-reanimated": "~4.1.0",
|
||||
"react-native-safe-area-context": "~5.6.0",
|
||||
"react-native-screens": "~4.16.0",
|
||||
"react-native-web": "^0.21.0",
|
||||
"react-native-worklets": "^0.5.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.26.10",
|
||||
"@types/react": "~19.0.10",
|
||||
"@types/react": "~19.1.10",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"typescript": "~5.8.2"
|
||||
},
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
const { hairlineWidth } = require("nativewind/theme");
|
||||
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
module.exports = {
|
||||
darkMode: "class",
|
||||
content: ["./app/**/*.{js,ts,tsx}", "./components/**/*.{js,ts,tsx}"],
|
||||
|
||||
presets: [require("nativewind/preset")],
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
background: "hsl(var(--background))",
|
||||
foreground: "hsl(var(--foreground))",
|
||||
card: {
|
||||
DEFAULT: "hsl(var(--card))",
|
||||
foreground: "hsl(var(--card-foreground))",
|
||||
},
|
||||
popover: {
|
||||
DEFAULT: "hsl(var(--popover))",
|
||||
foreground: "hsl(var(--popover-foreground))",
|
||||
},
|
||||
primary: {
|
||||
DEFAULT: "hsl(var(--primary))",
|
||||
foreground: "hsl(var(--primary-foreground))",
|
||||
},
|
||||
secondary: {
|
||||
DEFAULT: "hsl(var(--secondary))",
|
||||
foreground: "hsl(var(--secondary-foreground))",
|
||||
},
|
||||
muted: {
|
||||
DEFAULT: "hsl(var(--muted))",
|
||||
foreground: "hsl(var(--muted-foreground))",
|
||||
},
|
||||
accent: {
|
||||
DEFAULT: "hsl(var(--accent))",
|
||||
foreground: "hsl(var(--accent-foreground))",
|
||||
},
|
||||
destructive: {
|
||||
DEFAULT: "hsl(var(--destructive))",
|
||||
foreground: "hsl(var(--destructive-foreground))",
|
||||
},
|
||||
border: "hsl(var(--border))",
|
||||
input: "hsl(var(--input))",
|
||||
ring: "hsl(var(--ring))",
|
||||
radius: "var(--radius)",
|
||||
},
|
||||
borderRadius: {
|
||||
xl: "calc(var(--radius) + 4px)",
|
||||
lg: "var(--radius)",
|
||||
md: "calc(var(--radius) - 2px)",
|
||||
sm: "calc(var(--radius) - 4px)",
|
||||
},
|
||||
borderWidth: {
|
||||
hairline: hairlineWidth(),
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: [],
|
||||
};
|
||||
@@ -0,0 +1,59 @@
|
||||
import { hairlineWidth } from "nativewind/theme";
|
||||
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
export const darkMode = "class";
|
||||
export const content = [
|
||||
"./app/**/*.{js,ts,tsx}",
|
||||
"./components/**/*.{js,ts,tsx}",
|
||||
];
|
||||
export const presets = [require("nativewind/preset")];
|
||||
export const theme = {
|
||||
extend: {
|
||||
colors: {
|
||||
background: "hsl(var(--background))",
|
||||
foreground: "hsl(var(--foreground))",
|
||||
card: {
|
||||
DEFAULT: "hsl(var(--card))",
|
||||
foreground: "hsl(var(--card-foreground))",
|
||||
},
|
||||
popover: {
|
||||
DEFAULT: "hsl(var(--popover))",
|
||||
foreground: "hsl(var(--popover-foreground))",
|
||||
},
|
||||
primary: {
|
||||
DEFAULT: "hsl(var(--primary))",
|
||||
foreground: "hsl(var(--primary-foreground))",
|
||||
},
|
||||
secondary: {
|
||||
DEFAULT: "hsl(var(--secondary))",
|
||||
foreground: "hsl(var(--secondary-foreground))",
|
||||
},
|
||||
muted: {
|
||||
DEFAULT: "hsl(var(--muted))",
|
||||
foreground: "hsl(var(--muted-foreground))",
|
||||
},
|
||||
accent: {
|
||||
DEFAULT: "hsl(var(--accent))",
|
||||
foreground: "hsl(var(--accent-foreground))",
|
||||
},
|
||||
destructive: {
|
||||
DEFAULT: "hsl(var(--destructive))",
|
||||
foreground: "hsl(var(--destructive-foreground))",
|
||||
},
|
||||
border: "hsl(var(--border))",
|
||||
input: "hsl(var(--input))",
|
||||
ring: "hsl(var(--ring))",
|
||||
radius: "var(--radius)",
|
||||
},
|
||||
borderRadius: {
|
||||
xl: "calc(var(--radius) + 4px)",
|
||||
lg: "var(--radius)",
|
||||
md: "calc(var(--radius) - 2px)",
|
||||
sm: "calc(var(--radius) - 4px)",
|
||||
},
|
||||
borderWidth: {
|
||||
hairline: hairlineWidth(),
|
||||
},
|
||||
},
|
||||
};
|
||||
export const plugins = [];
|
||||
Reference in New Issue
Block a user