create-expo-stack 2.0.7 → 2.0.9
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/build/commands/create-expo-stack.js +65 -49
- package/build/templates/base/App.tsx.ejs +41 -0
- package/build/templates/base/app.json.ejs +43 -0
- package/build/templates/base/assets/adaptive-icon.png +0 -0
- package/build/templates/base/assets/favicon.png +0 -0
- package/build/templates/base/assets/icon.png +0 -0
- package/build/templates/base/assets/splash.png +0 -0
- package/build/templates/base/babel.config.js.ejs +17 -0
- package/build/templates/base/package.json.ejs +75 -0
- package/build/templates/base/tsconfig.json.ejs +16 -0
- package/build/templates/packages/expo-router/expo-env.d.ts +4 -0
- package/build/templates/packages/expo-router/index.ts +1 -0
- package/build/templates/packages/expo-router/metro.config.js +11 -0
- package/build/templates/packages/expo-router/stack/app/_layout.tsx.ejs +56 -0
- package/build/templates/packages/expo-router/stack/app/details.tsx.ejs +58 -0
- package/build/templates/packages/expo-router/stack/app/index.tsx.ejs +96 -0
- package/build/templates/packages/expo-router/tabs/app/(tabs)/_layout.tsx.ejs +57 -0
- package/build/templates/packages/expo-router/tabs/app/(tabs)/index.tsx.ejs +52 -0
- package/build/templates/packages/expo-router/tabs/app/(tabs)/two.tsx.ejs +52 -0
- package/build/templates/packages/expo-router/tabs/app/_layout.tsx.ejs +15 -0
- package/build/templates/packages/expo-router/tabs/app/modal.tsx.ejs +55 -0
- package/build/templates/packages/expo-router/tabs/components/edit-screen-info.tsx.ejs +84 -0
- package/build/templates/packages/nativewind/app.d.ts +2 -0
- package/build/templates/packages/nativewind/tailwind.config.js.ejs +16 -0
- package/build/templates/packages/react-navigation/App.tsx.ejs +8 -0
- package/build/templates/packages/react-navigation/components/edit-screen-info.tsx.ejs +99 -0
- package/build/templates/packages/react-navigation/navigation/index.tsx.ejs +98 -0
- package/build/templates/packages/react-navigation/navigation/tab-navigator.tsx.ejs +62 -0
- package/build/templates/packages/react-navigation/screens/details.tsx.ejs +61 -0
- package/build/templates/packages/react-navigation/screens/modal.tsx.ejs +57 -0
- package/build/templates/packages/react-navigation/screens/one.tsx.ejs +54 -0
- package/build/templates/packages/react-navigation/screens/overview.tsx.ejs +97 -0
- package/build/templates/packages/react-navigation/screens/two.tsx.ejs +54 -0
- package/package.json +3 -2
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import FontAwesome from "@expo/vector-icons/FontAwesome";
|
|
2
|
+
import { createBottomTabNavigator } from "@react-navigation/bottom-tabs";
|
|
3
|
+
import { Pressable, StyleSheet } from "react-native";
|
|
4
|
+
|
|
5
|
+
import One from "../screens/one";
|
|
6
|
+
import Two from "../screens/two";
|
|
7
|
+
|
|
8
|
+
const Tab = createBottomTabNavigator();
|
|
9
|
+
|
|
10
|
+
function TabBarIcon(props: {
|
|
11
|
+
name: React.ComponentProps<typeof FontAwesome>["name"];
|
|
12
|
+
color: string;
|
|
13
|
+
}) {
|
|
14
|
+
return <FontAwesome size={28} style={styles.tabBarIcon} {...props} />;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export default function TabLayout({ navigation }) {
|
|
18
|
+
return (
|
|
19
|
+
<Tab.Navigator
|
|
20
|
+
screenOptions={{
|
|
21
|
+
tabBarActiveTintColor: "black",
|
|
22
|
+
}}>
|
|
23
|
+
<Tab.Screen
|
|
24
|
+
name="One"
|
|
25
|
+
component={One}
|
|
26
|
+
options={{
|
|
27
|
+
title: "Tab One",
|
|
28
|
+
tabBarIcon: ({ color }) => <TabBarIcon name="code" color={color} />,
|
|
29
|
+
headerRight: () => (
|
|
30
|
+
<Pressable onPress={() => navigation.navigate("Modal")}>
|
|
31
|
+
{({ pressed }) => (
|
|
32
|
+
<FontAwesome
|
|
33
|
+
name="info-circle"
|
|
34
|
+
size={25}
|
|
35
|
+
color="gray"
|
|
36
|
+
style={[styles.headerRight, { opacity: pressed ? 0.5 : 1 }]}
|
|
37
|
+
/>
|
|
38
|
+
)}
|
|
39
|
+
</Pressable>
|
|
40
|
+
),
|
|
41
|
+
}}
|
|
42
|
+
/>
|
|
43
|
+
<Tab.Screen
|
|
44
|
+
name="Two"
|
|
45
|
+
component={Two}
|
|
46
|
+
options={{
|
|
47
|
+
title: "Tab Two",
|
|
48
|
+
tabBarIcon: ({ color }) => <TabBarIcon name="code" color={color} />,
|
|
49
|
+
}}
|
|
50
|
+
/>
|
|
51
|
+
</Tab.Navigator>
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const styles = StyleSheet.create({
|
|
56
|
+
headerRight: {
|
|
57
|
+
marginRight: 15
|
|
58
|
+
},
|
|
59
|
+
tabBarIcon: {
|
|
60
|
+
marginBottom: -3
|
|
61
|
+
}
|
|
62
|
+
});
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { RouteProp, useRoute } from "@react-navigation/native";
|
|
2
|
+
<% if (props.useNativewind) { %>
|
|
3
|
+
import { View, Text } from "react-native";
|
|
4
|
+
<% } else { %>
|
|
5
|
+
import { View, StyleSheet, Text } from "react-native";
|
|
6
|
+
<% } %>
|
|
7
|
+
import { RootStackParamList } from "../navigation";
|
|
8
|
+
|
|
9
|
+
type DetailsSreenRouteProp = RouteProp<RootStackParamList, "Details">;
|
|
10
|
+
|
|
11
|
+
export default function Details() {
|
|
12
|
+
const router = useRoute<DetailsSreenRouteProp>();
|
|
13
|
+
<% if (props.useNativewind) { %>
|
|
14
|
+
return (
|
|
15
|
+
<View className={styles.container}>
|
|
16
|
+
<View className={styles.main}>
|
|
17
|
+
<Text className={styles.title}>Details</Text>
|
|
18
|
+
<Text className={styles.subtitle}>Showing details for user {router.params.name}.</Text>
|
|
19
|
+
</View>
|
|
20
|
+
</View>
|
|
21
|
+
);
|
|
22
|
+
<% } else { %>
|
|
23
|
+
return (
|
|
24
|
+
<View style={styles.container}>
|
|
25
|
+
<View style={styles.main}>
|
|
26
|
+
<Text style={styles.title}>Details</Text>
|
|
27
|
+
<Text style={styles.subtitle}>Showing details for user {router.params.name}.</Text>
|
|
28
|
+
</View>
|
|
29
|
+
</View>
|
|
30
|
+
);
|
|
31
|
+
<% } %>
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
<% if (props.useNativewind) { %>
|
|
35
|
+
const styles = {
|
|
36
|
+
container: "flex-1 p-6",
|
|
37
|
+
main: "flex-1 max-w-[960]",
|
|
38
|
+
title: "text-[64px] font-bold",
|
|
39
|
+
subtitle: "text-4xl text-gray-700",
|
|
40
|
+
};
|
|
41
|
+
<% } else { %>
|
|
42
|
+
const styles = StyleSheet.create({
|
|
43
|
+
container: {
|
|
44
|
+
flex: 1,
|
|
45
|
+
padding: 24,
|
|
46
|
+
},
|
|
47
|
+
main: {
|
|
48
|
+
flex: 1,
|
|
49
|
+
maxWidth: 960,
|
|
50
|
+
marginHorizontal: "auto",
|
|
51
|
+
},
|
|
52
|
+
title: {
|
|
53
|
+
fontSize: 64,
|
|
54
|
+
fontWeight: "bold",
|
|
55
|
+
},
|
|
56
|
+
subtitle: {
|
|
57
|
+
fontSize: 36,
|
|
58
|
+
color: "#38434D",
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
<% } %>
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
<% if (props.useNativewind) { %>
|
|
2
|
+
import { Platform, Text, View } from "react-native";
|
|
3
|
+
<% } else { %>
|
|
4
|
+
import { Platform, StyleSheet, Text, View } from "react-native";
|
|
5
|
+
<% } %>
|
|
6
|
+
import { StatusBar } from "expo-status-bar";
|
|
7
|
+
|
|
8
|
+
import EditScreenInfo from "../components/edit-screen-info";
|
|
9
|
+
|
|
10
|
+
export default function Modal() {
|
|
11
|
+
<% if (props.useNativewind) { %>
|
|
12
|
+
return (
|
|
13
|
+
<View className={styles.container}>
|
|
14
|
+
<StatusBar style={Platform.OS === "ios" ? "light" : "auto"} />
|
|
15
|
+
<Text className={styles.title}>Modal</Text>
|
|
16
|
+
<View className={styles.separator} />
|
|
17
|
+
<EditScreenInfo path="src/screens/modal.tsx" />
|
|
18
|
+
</View>
|
|
19
|
+
)
|
|
20
|
+
<% } else { %>
|
|
21
|
+
return (
|
|
22
|
+
<View style={styles.container}>
|
|
23
|
+
<StatusBar style={Platform.OS === "ios" ? "light" : "auto"} />
|
|
24
|
+
<Text style={styles.title}>Modal</Text>
|
|
25
|
+
<View style={styles.separator} />
|
|
26
|
+
<EditScreenInfo path="src/screens/modal.tsx" />
|
|
27
|
+
</View>
|
|
28
|
+
);
|
|
29
|
+
<% } %>
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
<% if (props.useNativewind) { %>
|
|
33
|
+
const styles = {
|
|
34
|
+
container: "items-center flex-1 justify-center",
|
|
35
|
+
separator: "h-[1px] my-7 w-4/5 bg-gray-200",
|
|
36
|
+
title: "text-xl font-bold"
|
|
37
|
+
};
|
|
38
|
+
<% } else { %>
|
|
39
|
+
const styles = StyleSheet.create({
|
|
40
|
+
container: {
|
|
41
|
+
alignItems: "center",
|
|
42
|
+
flex: 1,
|
|
43
|
+
justifyContent: "center"
|
|
44
|
+
},
|
|
45
|
+
separator: {
|
|
46
|
+
backgroundColor: "gray",
|
|
47
|
+
height: 1,
|
|
48
|
+
marginVertical: 30,
|
|
49
|
+
opacity: 0.25,
|
|
50
|
+
width: "80%",
|
|
51
|
+
},
|
|
52
|
+
title: {
|
|
53
|
+
fontSize: 20,
|
|
54
|
+
fontWeight: "bold"
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
<% } %>
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
<% if (props.useNativewind) { %>
|
|
2
|
+
import { Text, View } from "react-native";
|
|
3
|
+
<% } else { %>
|
|
4
|
+
import { StyleSheet, Text, View } from "react-native";
|
|
5
|
+
<% } %>
|
|
6
|
+
|
|
7
|
+
import EditScreenInfo from "../components/edit-screen-info";
|
|
8
|
+
|
|
9
|
+
export default function TabOneScreen() {
|
|
10
|
+
<% if (props.useNativewind) { %>
|
|
11
|
+
return (
|
|
12
|
+
<View className={styles.container}>
|
|
13
|
+
<Text className={styles.title}>Tab One</Text>
|
|
14
|
+
<View className={styles.separator} />
|
|
15
|
+
<EditScreenInfo path="src/screens/one.tsx" />
|
|
16
|
+
</View>
|
|
17
|
+
);
|
|
18
|
+
<% } else { %>
|
|
19
|
+
return (
|
|
20
|
+
<View style={styles.container}>
|
|
21
|
+
<Text style={styles.title}>Tab One</Text>
|
|
22
|
+
<View style={styles.separator} />
|
|
23
|
+
<EditScreenInfo path="src/screens/one.tsx" />
|
|
24
|
+
</View>
|
|
25
|
+
);
|
|
26
|
+
<% } %>
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
<% if (props.useNativewind) { %>
|
|
30
|
+
const styles = {
|
|
31
|
+
container: "items-center flex-1 justify-center",
|
|
32
|
+
separator: "h-[1px] my-7 w-4/5 bg-gray-200",
|
|
33
|
+
title: "text-xl font-bold"
|
|
34
|
+
};
|
|
35
|
+
<% } else { %>
|
|
36
|
+
const styles = StyleSheet.create({
|
|
37
|
+
container: {
|
|
38
|
+
alignItems: "center",
|
|
39
|
+
flex: 1,
|
|
40
|
+
justifyContent: "center",
|
|
41
|
+
},
|
|
42
|
+
separator: {
|
|
43
|
+
backgroundColor: "gray",
|
|
44
|
+
height: 1,
|
|
45
|
+
marginVertical: 30,
|
|
46
|
+
opacity: 0.25,
|
|
47
|
+
width: "80%",
|
|
48
|
+
},
|
|
49
|
+
title: {
|
|
50
|
+
fontSize: 20,
|
|
51
|
+
fontWeight: "bold",
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
<% } %>
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { useNavigation } from "@react-navigation/native";
|
|
2
|
+
import { StackNavigationProp } from "@react-navigation/stack";
|
|
3
|
+
<% if (props.useNativewind) { %>
|
|
4
|
+
import { Text, TouchableOpacity, View } from "react-native";
|
|
5
|
+
<% } else { %>
|
|
6
|
+
import { StyleSheet, Text, TouchableOpacity, View } from "react-native";
|
|
7
|
+
<% } %>
|
|
8
|
+
import { RootStackParamList } from "../navigation";
|
|
9
|
+
|
|
10
|
+
type OverviewScreenNavigationProps = StackNavigationProp<RootStackParamList, "Overview">;
|
|
11
|
+
|
|
12
|
+
export default function Overview() {
|
|
13
|
+
const navigation = useNavigation<OverviewScreenNavigationProps>();
|
|
14
|
+
<% if (props.useNativewind) { %>
|
|
15
|
+
return (
|
|
16
|
+
<View className={styles.container}>
|
|
17
|
+
<View className={styles.main}>
|
|
18
|
+
<View>
|
|
19
|
+
<Text className={styles.title}>Hello World</Text>
|
|
20
|
+
<Text className={styles.subtitle}>This is the first page of your app.</Text>
|
|
21
|
+
</View>
|
|
22
|
+
<TouchableOpacity className={styles.button} onPress={() => navigation.navigate("Details", { name: "Dan" })}>
|
|
23
|
+
<Text className={styles.buttonText}>Show Details</Text>
|
|
24
|
+
</TouchableOpacity>
|
|
25
|
+
</View>
|
|
26
|
+
</View>
|
|
27
|
+
)
|
|
28
|
+
<% } else { %>
|
|
29
|
+
return (
|
|
30
|
+
<View style={styles.container}>
|
|
31
|
+
<View style={styles.main}>
|
|
32
|
+
<View>
|
|
33
|
+
<Text style={styles.title}>Hello World</Text>
|
|
34
|
+
<Text style={styles.subtitle}>This is the first page of your app.</Text>
|
|
35
|
+
</View>
|
|
36
|
+
<TouchableOpacity style={styles.button} onPress={() => navigation.navigate("Details", { name: "Dan" })}>
|
|
37
|
+
<Text style={styles.buttonText}>Show Details</Text>
|
|
38
|
+
</TouchableOpacity>
|
|
39
|
+
</View>
|
|
40
|
+
</View>
|
|
41
|
+
);
|
|
42
|
+
<% } %>
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
<% if (props.useNativewind) { %>
|
|
46
|
+
const styles = {
|
|
47
|
+
button: "items-center bg-indigo-500 rounded-[28px] shadow-md p-4",
|
|
48
|
+
buttonText: "text-white text-lg font-semibold text-center",
|
|
49
|
+
container: "flex-1 p-6",
|
|
50
|
+
main: "flex-1 max-w-[960] justify-between",
|
|
51
|
+
title: "text-[64px] font-bold",
|
|
52
|
+
subtitle: "text-4xl text-gray-700",
|
|
53
|
+
};
|
|
54
|
+
<% } else { %>
|
|
55
|
+
const styles = StyleSheet.create({
|
|
56
|
+
button: {
|
|
57
|
+
alignItems: "center",
|
|
58
|
+
backgroundColor: "#6366F1",
|
|
59
|
+
borderRadius: 24,
|
|
60
|
+
elevation: 5,
|
|
61
|
+
flexDirection: "row",
|
|
62
|
+
justifyContent: "center",
|
|
63
|
+
padding: 16,
|
|
64
|
+
shadowColor: "#000",
|
|
65
|
+
shadowOffset: {
|
|
66
|
+
height: 2,
|
|
67
|
+
width: 0
|
|
68
|
+
},
|
|
69
|
+
shadowOpacity: 0.25,
|
|
70
|
+
shadowRadius: 3.84
|
|
71
|
+
},
|
|
72
|
+
buttonText: {
|
|
73
|
+
color: "#FFFFFF",
|
|
74
|
+
fontSize: 16,
|
|
75
|
+
fontWeight: "600",
|
|
76
|
+
textAlign: "center",
|
|
77
|
+
},
|
|
78
|
+
container: {
|
|
79
|
+
flex: 1,
|
|
80
|
+
padding: 24,
|
|
81
|
+
},
|
|
82
|
+
main: {
|
|
83
|
+
flex: 1,
|
|
84
|
+
maxWidth: 960,
|
|
85
|
+
marginHorizontal: "auto",
|
|
86
|
+
justifyContent: "space-between",
|
|
87
|
+
},
|
|
88
|
+
title: {
|
|
89
|
+
fontSize: 64,
|
|
90
|
+
fontWeight: "bold",
|
|
91
|
+
},
|
|
92
|
+
subtitle: {
|
|
93
|
+
color: "#38434D",
|
|
94
|
+
fontSize: 36,
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
<% } %>
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
<% if (props.useNativewind) { %>
|
|
2
|
+
import { Text, View } from "react-native";
|
|
3
|
+
<% } else { %>
|
|
4
|
+
import { StyleSheet, Text, View } from "react-native";
|
|
5
|
+
<% } %>
|
|
6
|
+
|
|
7
|
+
import EditScreenInfo from "../components/edit-screen-info";
|
|
8
|
+
|
|
9
|
+
export default function TabOneScreen() {
|
|
10
|
+
<% if (props.useNativewind) { %>
|
|
11
|
+
return (
|
|
12
|
+
<View className={styles.container}>
|
|
13
|
+
<Text className={styles.title}>Tab One</Text>
|
|
14
|
+
<View className={styles.separator} />
|
|
15
|
+
<EditScreenInfo path="src/screens/one.tsx" />
|
|
16
|
+
</View>
|
|
17
|
+
);
|
|
18
|
+
<% } else { %>
|
|
19
|
+
return (
|
|
20
|
+
<View style={styles.container}>
|
|
21
|
+
<Text style={styles.title}>Tab Two</Text>
|
|
22
|
+
<View style={styles.separator} />
|
|
23
|
+
<EditScreenInfo path="src/screens/two.tsx" />
|
|
24
|
+
</View>
|
|
25
|
+
);
|
|
26
|
+
<% } %>
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
<% if (props.useNativewind) { %>
|
|
30
|
+
const styles = {
|
|
31
|
+
container: "items-center flex-1 justify-center",
|
|
32
|
+
separator: "h-[1px] my-7 w-4/5 bg-gray-200",
|
|
33
|
+
title: "text-xl font-bold"
|
|
34
|
+
};
|
|
35
|
+
<% } else { %>
|
|
36
|
+
const styles = StyleSheet.create({
|
|
37
|
+
container: {
|
|
38
|
+
alignItems: "center",
|
|
39
|
+
flex: 1,
|
|
40
|
+
justifyContent: "center",
|
|
41
|
+
},
|
|
42
|
+
separator: {
|
|
43
|
+
backgroundColor: "gray",
|
|
44
|
+
height: 1,
|
|
45
|
+
marginVertical: 30,
|
|
46
|
+
opacity: 0.25,
|
|
47
|
+
width: "80%",
|
|
48
|
+
},
|
|
49
|
+
title: {
|
|
50
|
+
fontSize: 20,
|
|
51
|
+
fontWeight: "bold",
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
<% } %>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-expo-stack",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.9",
|
|
4
4
|
"description": "create-expo-stack CLI",
|
|
5
5
|
"private": false,
|
|
6
6
|
"types": "build/types/types.d.ts",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"scripts": {
|
|
15
15
|
"clean-build": "rm -rf ./build",
|
|
16
16
|
"compile": "tsc -p .",
|
|
17
|
-
"copy-templates": "copyfiles ./src/templates
|
|
17
|
+
"copy-templates": "copyfiles -u 2 \"./src/templates/**/*\" ./build/templates",
|
|
18
18
|
"build": "yarn clean-build && yarn compile && yarn copy-templates && yarn lint-templates",
|
|
19
19
|
"prepublishOnly": "yarn build",
|
|
20
20
|
"format": "eslint \"**/*.{js,jsx,ts,tsx}\" --fix && prettier \"**/*.{js,jsx,ts,tsx,json}\" --write",
|
|
@@ -34,6 +34,7 @@
|
|
|
34
34
|
"license": "MIT",
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"ejs-lint": "^2.0.0",
|
|
37
|
+
"figlet": "^1.6.0",
|
|
37
38
|
"gluegun": "latest",
|
|
38
39
|
"gradient-string": "^2.0.2"
|
|
39
40
|
},
|