@mr.dj2u/create-expo-stack 2.21.3-mrdj.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.
Files changed (191) hide show
  1. package/README.md +435 -0
  2. package/bin/create-expo-stack.js +2 -0
  3. package/build/cli.js +49 -0
  4. package/build/commands/create-expo-stack.js +471 -0
  5. package/build/constants.js +39 -0
  6. package/build/templates/base/.gitignore.ejs +26 -0
  7. package/build/templates/base/.npmrc.ejs +1 -0
  8. package/build/templates/base/App.tsx.ejs +66 -0
  9. package/build/templates/base/app.json.ejs +69 -0
  10. package/build/templates/base/assets/adaptive-icon.png +0 -0
  11. package/build/templates/base/assets/favicon.png +0 -0
  12. package/build/templates/base/assets/icon.png +0 -0
  13. package/build/templates/base/assets/splash.png +0 -0
  14. package/build/templates/base/babel.config.js.ejs +38 -0
  15. package/build/templates/base/components/BackButton.tsx.ejs +23 -0
  16. package/build/templates/base/components/Button.tsx.ejs +42 -0
  17. package/build/templates/base/components/Container.tsx.ejs +14 -0
  18. package/build/templates/base/components/EditScreenInfo.tsx.ejs +44 -0
  19. package/build/templates/base/components/HeaderButton.tsx.ejs +31 -0
  20. package/build/templates/base/components/ScreenContent.tsx.ejs +40 -0
  21. package/build/templates/base/components/TabBarIcon.tsx.ejs +15 -0
  22. package/build/templates/base/eslint.config.js.ejs +15 -0
  23. package/build/templates/base/package.json.ejs +191 -0
  24. package/build/templates/base/prettier.config.js.ejs +11 -0
  25. package/build/templates/base/tsconfig.json.ejs +39 -0
  26. package/build/templates/packages/expo-router/drawer/app/(drawer)/(tabs)/_layout.tsx.ejs +40 -0
  27. package/build/templates/packages/expo-router/drawer/app/(drawer)/(tabs)/index.tsx.ejs +15 -0
  28. package/build/templates/packages/expo-router/drawer/app/(drawer)/(tabs)/two.tsx.ejs +15 -0
  29. package/build/templates/packages/expo-router/drawer/app/(drawer)/_layout.tsx.ejs +65 -0
  30. package/build/templates/packages/expo-router/drawer/app/(drawer)/index.tsx.ejs +15 -0
  31. package/build/templates/packages/expo-router/drawer/app/+html.tsx.ejs +49 -0
  32. package/build/templates/packages/expo-router/drawer/app/+not-found.tsx.ejs +100 -0
  33. package/build/templates/packages/expo-router/drawer/app/_layout.tsx.ejs +91 -0
  34. package/build/templates/packages/expo-router/drawer/app/modal.tsx.ejs +21 -0
  35. package/build/templates/packages/expo-router/expo-env.d.ts +4 -0
  36. package/build/templates/packages/expo-router/index.js.ejs +4 -0
  37. package/build/templates/packages/expo-router/metro.config.js.ejs +24 -0
  38. package/build/templates/packages/expo-router/stack/app/+html.tsx.ejs +49 -0
  39. package/build/templates/packages/expo-router/stack/app/+not-found.tsx.ejs +113 -0
  40. package/build/templates/packages/expo-router/stack/app/_layout.tsx.ejs +63 -0
  41. package/build/templates/packages/expo-router/stack/app/details.tsx.ejs +56 -0
  42. package/build/templates/packages/expo-router/stack/app/index.tsx.ejs +73 -0
  43. package/build/templates/packages/expo-router/tabs/app/(tabs)/_layout.tsx.ejs +52 -0
  44. package/build/templates/packages/expo-router/tabs/app/(tabs)/index.tsx.ejs +37 -0
  45. package/build/templates/packages/expo-router/tabs/app/(tabs)/two.tsx.ejs +37 -0
  46. package/build/templates/packages/expo-router/tabs/app/+html.tsx.ejs +49 -0
  47. package/build/templates/packages/expo-router/tabs/app/+not-found.tsx.ejs +110 -0
  48. package/build/templates/packages/expo-router/tabs/app/_layout.tsx.ejs +84 -0
  49. package/build/templates/packages/expo-router/tabs/app/modal.tsx.ejs +21 -0
  50. package/build/templates/packages/firebase/.env.ejs +8 -0
  51. package/build/templates/packages/firebase/metro.config.js.ejs +14 -0
  52. package/build/templates/packages/firebase/utils/firebase.ts.ejs +26 -0
  53. package/build/templates/packages/i18next/components/InternalizationExample.tsx.ejs +23 -0
  54. package/build/templates/packages/i18next/core/i18n/fallbackChecker.ts.ejs +13 -0
  55. package/build/templates/packages/i18next/core/i18n/init.ts.ejs +24 -0
  56. package/build/templates/packages/i18next/core/i18n/languageDetector.ts.ejs +13 -0
  57. package/build/templates/packages/i18next/translation/en.json.ejs +8 -0
  58. package/build/templates/packages/i18next/translation/fr.json.ejs +8 -0
  59. package/build/templates/packages/i18next/translation/index.ts.ejs +20 -0
  60. package/build/templates/packages/nativewind/components/BackButton.tsx.ejs +22 -0
  61. package/build/templates/packages/nativewind/components/Button.tsx.ejs +21 -0
  62. package/build/templates/packages/nativewind/components/Container.tsx.ejs +13 -0
  63. package/build/templates/packages/nativewind/components/EditScreenInfo.tsx.ejs +40 -0
  64. package/build/templates/packages/nativewind/components/ScreenContent.tsx.ejs +27 -0
  65. package/build/templates/packages/nativewind/global.css +3 -0
  66. package/build/templates/packages/nativewind/metro.config.js +7 -0
  67. package/build/templates/packages/nativewind/nativewind-env.d.ts +2 -0
  68. package/build/templates/packages/nativewind/tailwind.config.js.ejs +15 -0
  69. package/build/templates/packages/nativewindui/components/Container.tsx.ejs +14 -0
  70. package/build/templates/packages/nativewindui/components/EditScreenInfo.tsx.ejs +45 -0
  71. package/build/templates/packages/nativewindui/components/HeaderButton.tsx.ejs +31 -0
  72. package/build/templates/packages/nativewindui/components/ScreenContent.tsx.ejs +40 -0
  73. package/build/templates/packages/nativewindui/components/TabBarIcon.tsx.ejs +15 -0
  74. package/build/templates/packages/nativewindui/components/nativewindui/Icon/Icon.ios.tsx.ejs +52 -0
  75. package/build/templates/packages/nativewindui/components/nativewindui/Icon/Icon.tsx.ejs +58 -0
  76. package/build/templates/packages/nativewindui/components/nativewindui/Icon/index.ts.ejs +16 -0
  77. package/build/templates/packages/nativewindui/components/nativewindui/Icon/types.ts.ejs +18 -0
  78. package/build/templates/packages/nativewindui/components/nativewindui/ThemeToggle.tsx.ejs +33 -0
  79. package/build/templates/packages/nativewindui/drawer/app/(drawer)/(tabs)/_layout.tsx.ejs +28 -0
  80. package/build/templates/packages/nativewindui/drawer/app/(drawer)/(tabs)/index.tsx.ejs +15 -0
  81. package/build/templates/packages/nativewindui/drawer/app/(drawer)/(tabs)/two.tsx.ejs +15 -0
  82. package/build/templates/packages/nativewindui/drawer/app/(drawer)/_layout.tsx.ejs +35 -0
  83. package/build/templates/packages/nativewindui/drawer/app/(drawer)/index.tsx.ejs +535 -0
  84. package/build/templates/packages/nativewindui/drawer/app/+html.tsx.ejs +46 -0
  85. package/build/templates/packages/nativewindui/drawer/app/+not-found.tsx.ejs +83 -0
  86. package/build/templates/packages/nativewindui/drawer/app/_layout.tsx.ejs +75 -0
  87. package/build/templates/packages/nativewindui/drawer/app/modal.tsx.ejs +33 -0
  88. package/build/templates/packages/nativewindui/global.css.ejs +91 -0
  89. package/build/templates/packages/nativewindui/lib/cn.ts.ejs +6 -0
  90. package/build/templates/packages/nativewindui/lib/useColorScheme.tsx.ejs +21 -0
  91. package/build/templates/packages/nativewindui/nativewind-env.d.ts.ejs +1 -0
  92. package/build/templates/packages/nativewindui/stack/app/+html.tsx.ejs +46 -0
  93. package/build/templates/packages/nativewindui/stack/app/+not-found.tsx.ejs +18 -0
  94. package/build/templates/packages/nativewindui/stack/app/_layout.tsx.ejs +78 -0
  95. package/build/templates/packages/nativewindui/stack/app/index.tsx.ejs +487 -0
  96. package/build/templates/packages/nativewindui/stack/app/modal.tsx.ejs +33 -0
  97. package/build/templates/packages/nativewindui/tabs/app/(tabs)/_layout.tsx.ejs +35 -0
  98. package/build/templates/packages/nativewindui/tabs/app/(tabs)/index.tsx.ejs +537 -0
  99. package/build/templates/packages/nativewindui/tabs/app/(tabs)/two.tsx.ejs +22 -0
  100. package/build/templates/packages/nativewindui/tabs/app/+html.tsx.ejs +46 -0
  101. package/build/templates/packages/nativewindui/tabs/app/+not-found.tsx.ejs +90 -0
  102. package/build/templates/packages/nativewindui/tabs/app/_layout.tsx.ejs +78 -0
  103. package/build/templates/packages/nativewindui/tabs/app/modal.tsx.ejs +21 -0
  104. package/build/templates/packages/nativewindui/tailwind.config.js.ejs +67 -0
  105. package/build/templates/packages/nativewindui/theme/colors.ts.ejs +123 -0
  106. package/build/templates/packages/nativewindui/theme/index.ts.ejs +32 -0
  107. package/build/templates/packages/nativewindui/theme/with-opacity.ts.ejs +155 -0
  108. package/build/templates/packages/react-navigation/App.tsx.ejs +73 -0
  109. package/build/templates/packages/react-navigation/navigation/drawer-navigator.tsx.ejs +31 -0
  110. package/build/templates/packages/react-navigation/navigation/index.tsx.ejs +108 -0
  111. package/build/templates/packages/react-navigation/navigation/tab-navigator.tsx.ejs +38 -0
  112. package/build/templates/packages/react-navigation/screens/details.tsx.ejs +41 -0
  113. package/build/templates/packages/react-navigation/screens/home.tsx.ejs +5 -0
  114. package/build/templates/packages/react-navigation/screens/modal.tsx.ejs +20 -0
  115. package/build/templates/packages/react-navigation/screens/one.tsx.ejs +5 -0
  116. package/build/templates/packages/react-navigation/screens/overview.tsx.ejs +54 -0
  117. package/build/templates/packages/react-navigation/screens/two.tsx.ejs +5 -0
  118. package/build/templates/packages/restyle/components/BackButton.tsx.ejs +19 -0
  119. package/build/templates/packages/restyle/components/Button.tsx.ejs +32 -0
  120. package/build/templates/packages/restyle/components/Container.tsx.ejs +16 -0
  121. package/build/templates/packages/restyle/components/EditScreenInfo.tsx.ejs +38 -0
  122. package/build/templates/packages/restyle/components/ScreenContent.tsx.ejs +30 -0
  123. package/build/templates/packages/restyle/theme.ts.ejs +51 -0
  124. package/build/templates/packages/supabase/.env.ejs +2 -0
  125. package/build/templates/packages/supabase/utils/supabase.ts.ejs +14 -0
  126. package/build/templates/packages/tamagui/components/BackButton.tsx.ejs +12 -0
  127. package/build/templates/packages/tamagui/components/Button.tsx.ejs +17 -0
  128. package/build/templates/packages/tamagui/components/Container.tsx.ejs +12 -0
  129. package/build/templates/packages/tamagui/components/EditScreenInfo.tsx.ejs +27 -0
  130. package/build/templates/packages/tamagui/components/ScreenContent.tsx.ejs +23 -0
  131. package/build/templates/packages/tamagui/tamagui.config.ts.ejs +14 -0
  132. package/build/templates/packages/unistyles/breakpoints.ts.ejs +9 -0
  133. package/build/templates/packages/unistyles/components/BackButton.tsx.ejs +28 -0
  134. package/build/templates/packages/unistyles/components/Button.tsx.ejs +42 -0
  135. package/build/templates/packages/unistyles/components/Container.tsx.ejs +17 -0
  136. package/build/templates/packages/unistyles/components/EditScreenInfo.tsx.ejs +53 -0
  137. package/build/templates/packages/unistyles/components/ScreenContent.tsx.ejs +43 -0
  138. package/build/templates/packages/unistyles/theme.ts.ejs +34 -0
  139. package/build/templates/packages/unistyles/unistyles.ts.ejs +27 -0
  140. package/build/templates/packages/uniwind/global.css +2 -0
  141. package/build/templates/packages/uniwind/metro.config.js.ejs +10 -0
  142. package/build/templates/packages/vexo-analytics/.env.ejs +7 -0
  143. package/build/templates/packages/zustand/store/store.ts.ejs +15 -0
  144. package/build/types/cli.d.ts +4 -0
  145. package/build/types/commands/create-expo-stack.d.ts +3 -0
  146. package/build/types/constants.d.ts +10 -0
  147. package/build/types/types.d.ts +33 -0
  148. package/build/types/utilities/bumpVersion.d.ts +1 -0
  149. package/build/types/utilities/clearNavigationPackages.d.ts +2 -0
  150. package/build/types/utilities/clearStylingPackages.d.ts +2 -0
  151. package/build/types/utilities/configAnalytics.d.ts +18 -0
  152. package/build/types/utilities/configStorage.d.ts +8 -0
  153. package/build/types/utilities/configureProjectFiles.d.ts +3 -0
  154. package/build/types/utilities/copyBaseAssets.d.ts +2 -0
  155. package/build/types/utilities/generateNWUI.d.ts +3 -0
  156. package/build/types/utilities/generateProjectFiles.d.ts +5 -0
  157. package/build/types/utilities/getPackageManager.d.ts +8 -0
  158. package/build/types/utilities/index.d.ts +10 -0
  159. package/build/types/utilities/printOutput.d.ts +3 -0
  160. package/build/types/utilities/publishToGitHub.d.ts +2 -0
  161. package/build/types/utilities/renderTitle.d.ts +2 -0
  162. package/build/types/utilities/runCLI.d.ts +3 -0
  163. package/build/types/utilities/runEasConfigure.d.ts +3 -0
  164. package/build/types/utilities/runIgnite.d.ts +3 -0
  165. package/build/types/utilities/showHelp.d.ts +1 -0
  166. package/build/types/utilities/systemCommand.d.ts +14 -0
  167. package/build/types/utilities/usePackage.d.ts +2 -0
  168. package/build/types/utilities/validateProjectName.d.ts +4 -0
  169. package/build/types.js +39 -0
  170. package/build/utilities/bumpVersion.js +21 -0
  171. package/build/utilities/clearNavigationPackages.js +11 -0
  172. package/build/utilities/clearStylingPackages.js +11 -0
  173. package/build/utilities/configAnalytics.js +70 -0
  174. package/build/utilities/configStorage.js +50 -0
  175. package/build/utilities/configureProjectFiles.js +380 -0
  176. package/build/utilities/copyBaseAssets.js +21 -0
  177. package/build/utilities/generateNWUI.js +54 -0
  178. package/build/utilities/generateProjectFiles.js +106 -0
  179. package/build/utilities/getPackageManager.js +103 -0
  180. package/build/utilities/index.js +27 -0
  181. package/build/utilities/printOutput.js +251 -0
  182. package/build/utilities/publishToGitHub.js +173 -0
  183. package/build/utilities/renderTitle.js +55 -0
  184. package/build/utilities/runCLI.js +437 -0
  185. package/build/utilities/runEasConfigure.js +83 -0
  186. package/build/utilities/runIgnite.js +26 -0
  187. package/build/utilities/showHelp.js +85 -0
  188. package/build/utilities/systemCommand.js +40 -0
  189. package/build/utilities/usePackage.js +8 -0
  190. package/build/utilities/validateProjectName.js +42 -0
  191. package/package.json +77 -0
@@ -0,0 +1,69 @@
1
+ {
2
+ "expo": {
3
+ "name": "<%= props.projectName %>",
4
+ "slug": "<%= props.projectName %>",
5
+ "version": "1.0.0",
6
+ <% if (props.stylingPackage?.name === "unistyles") { %>
7
+ "newArchEnabled": true,
8
+ <% } %>
9
+ <% if (props.navigationPackage?.name === 'expo-router') { %>
10
+ "scheme": "<%= props.projectName %>",
11
+ "platforms": ["ios", "android"],
12
+ "web": {
13
+ "bundler": "metro",
14
+ "output": "static",
15
+ "favicon": "./assets/favicon.png"
16
+ },
17
+ "plugins": [
18
+ "expo-router"
19
+ <% if (props.internalizationPackage?.name === "i18next") { %>
20
+ ,"expo-localization"
21
+ <% } %>
22
+ ],
23
+ "experiments": {
24
+ "typedRoutes": true
25
+ <% if (props.flags.importAlias) { %>
26
+ ,"tsconfigPaths": true
27
+ <% } %>
28
+ },
29
+ <% } else { %>
30
+ "web": {
31
+ "favicon": "./assets/favicon.png"
32
+ },
33
+ <% if (props.flags.importAlias) { %>
34
+ "experiments": {
35
+ "tsconfigPaths": true
36
+ },
37
+ <% } %>
38
+ "plugins": [
39
+ <% if (props.internalizationPackage?.name === "i18next") { %>
40
+ "expo-localization"
41
+ <% } %>
42
+ ],
43
+ <% } %>
44
+ "orientation": "portrait",
45
+ "icon": "./assets/icon.png",
46
+ <% if (props.stylingPackage?.name === "nativewindui" || props.stylingPackage?.name === "unistyles") { %>
47
+ "userInterfaceStyle": "automatic",
48
+ <% } else { %>
49
+ "userInterfaceStyle": "light",
50
+ <% } %>
51
+ "splash": {
52
+ "image": "./assets/splash.png",
53
+ "resizeMode": "contain",
54
+ "backgroundColor": "#ffffff"
55
+ },
56
+ "assetBundlePatterns": [
57
+ "**/*"
58
+ ],
59
+ "ios": {
60
+ "supportsTablet": true
61
+ },
62
+ "android": {
63
+ "adaptiveIcon": {
64
+ "foregroundImage": "./assets/adaptive-icon.png",
65
+ "backgroundColor": "#ffffff"
66
+ }
67
+ }
68
+ }
69
+ }
@@ -0,0 +1,38 @@
1
+ module.exports = function(api) {
2
+ api.cache(true);
3
+ let plugins = [];
4
+
5
+ <% if (props.stylingPackage?.name === "unistyles") { %>
6
+ plugins.push([
7
+ 'react-native-unistyles/plugin',
8
+ {
9
+ autoProcessRoot: 'app',
10
+ autoProcessImports: ['~/components']
11
+ }
12
+ ]);
13
+ <% } %>
14
+
15
+ <% if (props.stylingPackage?.name === "tamagui") { %>
16
+ plugins.push([
17
+ '@tamagui/babel-plugin',
18
+ {
19
+ config: './tamagui.config.ts',
20
+ components: ['tamagui']
21
+ }
22
+ ]);
23
+ <% } %>
24
+
25
+ plugins.push('react-native-worklets/plugin');
26
+
27
+ return {
28
+ <% if (props.stylingPackage?.name === "nativewind" || props.stylingPackage?.name === "nativewindui") { %>
29
+ presets: [
30
+ ['babel-preset-expo', { jsxImportSource: 'nativewind' }],
31
+ 'nativewind/babel',
32
+ ],
33
+ <% } else { %>
34
+ presets: ['babel-preset-expo'],
35
+ <% } %>
36
+ plugins,
37
+ };
38
+ };
@@ -0,0 +1,23 @@
1
+ import { Feather } from '@expo/vector-icons';
2
+ import { Text, View, StyleSheet } from 'react-native';
3
+
4
+ export const BackButton = ({ onPress }: { onPress: () => void }) => {
5
+ return (
6
+ <View style={styles.backButton}>
7
+ <Feather name="chevron-left" size={16} color="#007AFF" />
8
+ <Text style={styles.backButtonText} onPress={onPress}>
9
+ Back
10
+ </Text>
11
+ </View>
12
+ );
13
+ };
14
+ const styles = StyleSheet.create({
15
+ backButton: {
16
+ flexDirection: 'row',
17
+ paddingLeft: 20,
18
+ },
19
+ backButtonText: {
20
+ color: '#007AFF',
21
+ marginLeft: 4,
22
+ },
23
+ });
@@ -0,0 +1,42 @@
1
+ import { forwardRef } from 'react';
2
+ import { StyleSheet, Text, TouchableOpacity, TouchableOpacityProps, View } from 'react-native';
3
+
4
+ type ButtonProps = {
5
+ title?: string;
6
+ } & TouchableOpacityProps;
7
+
8
+ export const Button = forwardRef<View, ButtonProps>(({ title, ...touchableProps }, ref) => {
9
+ return (
10
+ <TouchableOpacity ref={ref} {...touchableProps} style={[styles.button, touchableProps.style]}>
11
+ <Text style={styles.buttonText}>{title}</Text>
12
+ </TouchableOpacity>
13
+ );
14
+ });
15
+
16
+ Button.displayName = 'Button';
17
+
18
+ const styles = StyleSheet.create({
19
+ button: {
20
+ alignItems: 'center',
21
+ backgroundColor: '#6366F1',
22
+ borderRadius: 24,
23
+ elevation: 5,
24
+ flexDirection: 'row',
25
+ justifyContent: 'center',
26
+ marginHorizontal: 16,
27
+ padding: 16,
28
+ shadowColor: '#000',
29
+ shadowOffset: {
30
+ height: 2,
31
+ width: 0,
32
+ },
33
+ shadowOpacity: 0.25,
34
+ shadowRadius: 3.84,
35
+ },
36
+ buttonText: {
37
+ color: '#FFFFFF',
38
+ fontSize: 16,
39
+ fontWeight: '600',
40
+ textAlign: 'center',
41
+ },
42
+ });
@@ -0,0 +1,14 @@
1
+ import { StyleSheet, SafeAreaView } from 'react-native';
2
+
3
+ export const Container = ({ children }: { children: React.ReactNode }) => {
4
+ return <SafeAreaView style={styles.container}>{children}</SafeAreaView>;
5
+ };
6
+
7
+ const styles = StyleSheet.create({
8
+ container: {
9
+ flex: 1,
10
+ padding: 24,
11
+ backgroundColor: 'white',
12
+ },
13
+ });
14
+
@@ -0,0 +1,44 @@
1
+ import { StyleSheet, Text, View } from 'react-native';
2
+
3
+ <% if (props.internalizationPackage?.name === "i18next") { %>
4
+ import { useTranslation } from 'react-i18next';
5
+ <% } %>
6
+
7
+ export default function EditScreenInfo({ path }: { path: string }) {
8
+ <% if (props.internalizationPackage?.name === "i18next") { %>
9
+ const { t } = useTranslation();
10
+ const title = t('getStarted');
11
+ const description = t('changeCode')
12
+ <% } else { %>
13
+ const title = "Open up the code for this screen:"
14
+ const description = "Change any of the text, save the file, and your app will automatically update."
15
+ <% } %>
16
+ return (
17
+ <View style={styles.getStartedContainer}>
18
+ <Text style={styles.getStartedText}>{title}</Text>
19
+ <View style={[styles.codeHighlightContainer, styles.homeScreenFilename]}>
20
+ <Text>{path}</Text>
21
+ </View>
22
+ <Text style={styles.getStartedText}>{description}</Text>
23
+ </View>
24
+ );
25
+ }
26
+
27
+ const styles = StyleSheet.create({
28
+ codeHighlightContainer: {
29
+ borderRadius: 3,
30
+ paddingHorizontal: 4,
31
+ },
32
+ getStartedContainer: {
33
+ alignItems: 'center',
34
+ marginHorizontal: 50,
35
+ },
36
+ getStartedText: {
37
+ fontSize: 17,
38
+ lineHeight: 24,
39
+ textAlign: 'center',
40
+ },
41
+ homeScreenFilename: {
42
+ marginVertical: 7,
43
+ },
44
+ });
@@ -0,0 +1,31 @@
1
+ import { forwardRef } from 'react';
2
+ import FontAwesome from '@expo/vector-icons/FontAwesome';
3
+ import { Pressable, StyleSheet } from 'react-native';
4
+
5
+ export const HeaderButton = forwardRef<typeof Pressable, { onPress?: () => void; }>(({ onPress }, ref) => {
6
+ return (
7
+ <Pressable onPress={onPress}>
8
+ {({ pressed }) => (
9
+ <FontAwesome
10
+ name="info-circle"
11
+ size={25}
12
+ color="gray"
13
+ style={[
14
+ styles.headerRight,
15
+ {
16
+ opacity: pressed ? 0.5 : 1,
17
+ },
18
+ ]}
19
+ />
20
+ )}
21
+ </Pressable>
22
+ );
23
+ });
24
+
25
+ HeaderButton.displayName = 'HeaderButton';
26
+
27
+ export const styles = StyleSheet.create({
28
+ headerRight: {
29
+ marginRight: 15,
30
+ },
31
+ });
@@ -0,0 +1,40 @@
1
+ import React from 'react';
2
+ import { StyleSheet, Text, View } from 'react-native';
3
+
4
+ import EditScreenInfo from './EditScreenInfo';
5
+
6
+ type ScreenContentProps = {
7
+ title: string;
8
+ path: string;
9
+ children?: React.ReactNode;
10
+ };
11
+
12
+ export const ScreenContent = ({ title, path, children }: ScreenContentProps) => {
13
+ return (
14
+ <View style={styles.container}>
15
+ <Text style={styles.title}>{title}</Text>
16
+ <View style={styles.separator} />
17
+ <EditScreenInfo path={path} />
18
+ {children}
19
+ </View>
20
+ );
21
+ };
22
+
23
+ const styles = StyleSheet.create({
24
+ container: {
25
+ alignItems: 'center',
26
+ backgroundColor: 'white',
27
+ flex: 1,
28
+ justifyContent: 'center',
29
+ },
30
+ separator: {
31
+ backgroundColor: '#d1d5db',
32
+ height: 1,
33
+ marginVertical: 30,
34
+ width: '80%',
35
+ },
36
+ title: {
37
+ fontSize: 20,
38
+ fontWeight: 'bold',
39
+ },
40
+ });
@@ -0,0 +1,15 @@
1
+ import FontAwesome from '@expo/vector-icons/FontAwesome';
2
+ import { StyleSheet } from 'react-native';
3
+
4
+ export const TabBarIcon = (props: {
5
+ name: React.ComponentProps<typeof FontAwesome>['name'];
6
+ color: string;
7
+ }) => {
8
+ return <FontAwesome size={28} style={styles.tabBarIcon} {...props} />;
9
+ };
10
+
11
+ export const styles = StyleSheet.create({
12
+ tabBarIcon: {
13
+ marginBottom: -3,
14
+ },
15
+ });
@@ -0,0 +1,15 @@
1
+ /* eslint-env node */
2
+ const { defineConfig } = require('eslint/config');
3
+ const expoConfig = require('eslint-config-expo/flat');
4
+
5
+ module.exports = defineConfig([
6
+ expoConfig,
7
+ {
8
+ ignores: ['dist/*'],
9
+ },
10
+ {
11
+ rules: {
12
+ 'react/display-name': 'off',
13
+ },
14
+ },
15
+ ]);
@@ -0,0 +1,191 @@
1
+ {
2
+ "name": "<%= props.projectName %>",
3
+ "version": "1.0.0",
4
+ <% if (props.navigationPackage?.name === "expo-router" && props.stylingPackage?.name === 'unistyles') { %>
5
+ "main": "index.js",
6
+ <% } else if (props.navigationPackage?.name === "expo-router") { %>
7
+ "main": "expo-router/entry",
8
+ <% } %>
9
+ "scripts": {
10
+ <% if (props.flags?.eas) { %>
11
+ "start": "expo start --dev-client",
12
+ "ios": "expo run:ios",
13
+ "android": "expo run:android",
14
+ "build:dev": "eas build --profile development",
15
+ "build:preview": "eas build --profile preview",
16
+ "build:prod": "eas build --profile production",
17
+ "prebuild": "expo prebuild",
18
+ <% } else if (props.stylingPackage?.name === "nativewind" || props.stylingPackage?.name === "uniwind") { %>
19
+ "android": "expo start --android",
20
+ "ios": "expo start --ios",
21
+ "start": "expo start",
22
+ "prebuild": "expo prebuild",
23
+ <% } else { %>
24
+ "android": "expo start --android",
25
+ "ios": "expo start --ios",
26
+ "start": "expo start",
27
+ <% } %>
28
+ "lint": "eslint \"**/*.{js,jsx,ts,tsx}\" && prettier -c \"**/*.{js,jsx,ts,tsx,json}\"",
29
+ "format": "eslint \"**/*.{js,jsx,ts,tsx}\" --fix && prettier \"**/*.{js,jsx,ts,tsx,json}\" --write",
30
+ "web": "expo start --web"
31
+ },
32
+ "dependencies": {
33
+ <% if (props.stylingPackage?.name === "nativewind" || props.stylingPackage?.name === "nativewindui") { %>
34
+ "nativewind": "latest",
35
+ <% } %>
36
+ <% if (props.stylingPackage?.name === "uniwind") { %>
37
+ "uniwind": "^1.6.4",
38
+ <% } %>
39
+ <% if (props.stylingPackage?.name === "restyle") { %>
40
+ "@shopify/restyle": "^2.4.4",
41
+ <% } %>
42
+ <% if (props.stylingPackage?.name === "tamagui") { %>
43
+ "@tamagui/config": "^1.118.0",
44
+ "tamagui": "^1.118.0",
45
+ <% } %>
46
+ <% if (props.stylingPackage?.name === "nativewindui") { %>
47
+ "@shopify/flash-list": "2.0.2",
48
+ "class-variance-authority": "^0.7.0",
49
+ "clsx": "^2.1.0",
50
+ "tailwind-merge": "^2.2.1",
51
+ "react-native-uitextview": "^1.1.4",
52
+ "rn-icon-mapper": "^0.0.1",
53
+ "expo-haptics": "~55.0.14",
54
+ "expo-symbols": "~55.0.8",
55
+ <% if (props.stylingPackage?.options.selectedComponents.includes('date-picker')) { %>
56
+ "@react-native-community/datetimepicker": "8.6.0",
57
+ <% } %>
58
+ <% if (props.stylingPackage?.options.selectedComponents.includes('picker')) { %>
59
+ "@react-native-picker/picker": "2.11.4",
60
+ <% } %>
61
+ <% if (props.stylingPackage?.options.selectedComponents.includes('action-sheet')) { %>
62
+ "@expo/react-native-action-sheet": "^4.0.1",
63
+ <% } %>
64
+ <% if (props.stylingPackage?.options.selectedComponents.includes('ratings-indicator')) { %>
65
+ "expo-store-review": "~55.0.13",
66
+ <% } %>
67
+ <% if (props.stylingPackage?.options.selectedComponents.includes('slider')) { %>
68
+ "@react-native-community/slider": "5.1.2",
69
+ <% } %>
70
+ <% } %>
71
+
72
+ <% if (props.stateManagementPackage?.name === "zustand") { %>
73
+ "zustand": "^4.5.1",
74
+ <% } %>
75
+
76
+ <% if (props.stylingPackage?.name === "unistyles") { %>
77
+ "react-native-unistyles": "3.0.0-rc.4",
78
+ "react-native-nitro-modules": "0.25.2",
79
+ "react-native-edge-to-edge": "1.6.0",
80
+ <% } %>
81
+
82
+ <% if (props.navigationPackage?.type === "navigation") { %>
83
+ "@react-navigation/native": "^7.1.6",
84
+ <% } %>
85
+
86
+ <% if (props.navigationPackage?.type === "navigation" || props.packages?.some((p) => p.name === "react-native-gesture-handler")) { %>
87
+ "react-native-gesture-handler": "~2.30.0",
88
+ <% } %>
89
+
90
+ <% if (props.navigationPackage?.type === "navigation" || props.packages?.some((p) => p.name === "react-native-screens")) { %>
91
+ "react-native-screens": "~4.23.0",
92
+ <% } %>
93
+
94
+ <% if (props.packages?.some((p) => p.name === "react-native-svg")) { %>
95
+ "react-native-svg": "15.15.3",
96
+ <% } %>
97
+
98
+ <% if (props.packages?.some((p) => p.name === "react-native-keyboard-controller")) { %>
99
+ "react-native-keyboard-controller": "1.20.7",
100
+ <% } %>
101
+
102
+ <% if (props.navigationPackage?.name === "react-navigation") { %>
103
+ "@react-navigation/stack": "^7.4.8",
104
+ "@expo/vector-icons": "^15.0.2",
105
+ "expo-font": "~55.0.7",
106
+ <% } %>
107
+
108
+ <% if (props.analyticsPackage?.name === "vexo-analytics") { %>
109
+ "vexo-analytics": "^1.3.15",
110
+ <% } %>
111
+
112
+ <% if (props.navigationPackage?.options.type === "tabs" && props.navigationPackage?.name === "react-navigation") { %>
113
+ "@react-navigation/bottom-tabs": "^7.0.5",
114
+ <% } %>
115
+
116
+ <% if ((props.navigationPackage?.options.type === "drawer + tabs") && (props.navigationPackage?.name === "react-navigation")) { %>
117
+ "@react-navigation/drawer": "^7.0.0",
118
+ "@react-navigation/bottom-tabs": "^7.0.5",
119
+ <% } else if (props.navigationPackage?.options.type === "drawer + tabs") { %>
120
+ "@react-navigation/drawer": "^7.0.0",
121
+ "@react-navigation/bottom-tabs": "^7.0.5",
122
+ <% } %>
123
+
124
+ <% if (props.navigationPackage?.name === "expo-router") { %>
125
+ "@expo/log-box": "55.0.12",
126
+ "@expo/vector-icons": "^15.0.2",
127
+ "expo-font": "~55.0.7",
128
+ "expo-linking": "~55.0.15",
129
+ "expo-router": "~55.0.14",
130
+ "expo-constants": "~55.0.16",
131
+ "expo-system-ui": "~55.0.17",
132
+ "expo-web-browser": "~55.0.15",
133
+ "react-dom": "19.2.0",
134
+ "react-native-web": "~0.21.0",
135
+ <% } %>
136
+
137
+ <% if (props.authenticationPackage?.name === "supabase") { %>
138
+ "@react-native-async-storage/async-storage": "2.2.0",
139
+ "@supabase/supabase-js": "^2.38.4",
140
+ <% } %>
141
+
142
+ <% if (props.authenticationPackage?.name === "firebase") { %>
143
+ "firebase": "^12.13.0",
144
+ <% } %>
145
+
146
+ <% if (props.internalizationPackage?.name === "i18next") { %>
147
+ "i18next": "^23.7.20",
148
+ "react-i18next": "^14.0.1",
149
+ "expo-localization": "~55.0.13",
150
+ <% } %>
151
+ <% if (props.flags?.eas || props.stylingPackage?.name === "nativewindui") { %>
152
+ "expo-dev-client": "~55.0.32",
153
+ "expo-device": "~55.0.16",
154
+ <% } %>
155
+
156
+ "react-native-reanimated": "4.2.1",
157
+ "react-native-worklets": "0.7.4",
158
+
159
+ "react-native-safe-area-context": "~5.6.2",
160
+ "expo": "~55.0.23",
161
+ "expo-status-bar": "~55.0.6",
162
+ "react": "19.2.0",
163
+ "react-native": "0.83.6"
164
+ },
165
+ "devDependencies": {
166
+ "@babel/core": "^7.20.0",
167
+ "@types/react": "~19.2.2",
168
+ "eslint": "^9.25.1",
169
+ "eslint-config-expo": "~55.0.0",
170
+ "eslint-config-prettier": "^10.1.2",
171
+ "prettier": "^3.2.5",
172
+ <% if (props.stylingPackage?.name === "nativewind" || props.stylingPackage?.name === "nativewindui") { %>
173
+ "tailwindcss": "^3.4.0",
174
+ "prettier-plugin-tailwindcss": "^0.5.11",
175
+ <% } %>
176
+ <% if (props.stylingPackage?.name === "uniwind") { %>
177
+ "tailwindcss": "^4.2.4",
178
+ <% } %>
179
+ <% if (props.stylingPackage?.name === "tamagui") { %>
180
+ "@tamagui/babel-plugin": "^1.118.0",
181
+ <% } %>
182
+ "typescript": "~5.9.2"
183
+ },
184
+ <% if (props.navigationPackage?.name !== "expo-router") { %>
185
+ "main": "node_modules/expo/AppEntry.js",
186
+ <% } %>
187
+ <% if (props.packageManager === "yarn"){ %>
188
+ "packageManager": "yarn@4.9.4",
189
+ <% } %>
190
+ "private": true
191
+ }
@@ -0,0 +1,11 @@
1
+ module.exports = {
2
+ printWidth: 100,
3
+ tabWidth: 2,
4
+ singleQuote: true,
5
+ bracketSameLine: true,
6
+ trailingComma: 'es5',
7
+ <% if (props.stylingPackage?.name === "nativewind" || props.stylingPackage?.name === "nativewindui") { %>
8
+ plugins: [require.resolve("prettier-plugin-tailwindcss")],
9
+ tailwindAttributes: ["className"],
10
+ <% } %>
11
+ };
@@ -0,0 +1,39 @@
1
+ {
2
+ "extends": "expo/tsconfig.base",
3
+ "compilerOptions": {
4
+ <% if (props.flags.importAlias) { %>
5
+ "strict": true,
6
+ "baseUrl": ".",
7
+ "paths": {
8
+ <% if (props.stylingPackage?.name === 'nativewindui') { %>
9
+ "@/*": [ "./*" ]
10
+ <% } else { %>
11
+ <% if (props.navigationPackage?.name === "expo-router" && props.flags.importAlias === true) { %>
12
+ "@/*": ["*"]
13
+ <% } else if (props.flags.importAlias === true) { %>
14
+ "@/*": ["src/*"]
15
+ <% } else { %>
16
+ "<%= props.flags.importAlias %>": ["src/*"]
17
+ <% } %>
18
+ <% } %>
19
+ }
20
+ <% } else { %>
21
+ "strict": true
22
+ <% } %>
23
+ <% if (props.navigationPackage?.name === 'expo-router') { %>
24
+ },
25
+ "include": [
26
+ "**/*.ts",
27
+ "**/*.tsx",
28
+ ".expo/types/**/*.ts",
29
+ <% if (props.stylingPackage?.name === 'nativewind' || props.stylingPackage?.name === 'nativewindui') { %>
30
+ "expo-env.d.ts",
31
+ "nativewind-env.d.ts"
32
+ <% } else { %>
33
+ "expo-env.d.ts"
34
+ <% } %>
35
+ ]
36
+ <% } else { %>
37
+ }
38
+ <% } %>
39
+ }
@@ -0,0 +1,40 @@
1
+ import { Tabs } from 'expo-router';
2
+ import { TabBarIcon } from '@/components/TabBarIcon';
3
+ <% if (props.stylingPackage?.name === "unistyles") { %>
4
+ import { useUnistyles } from "react-native-unistyles";
5
+ <% } %>
6
+
7
+ export default function TabLayout() {
8
+ <% if (props.stylingPackage?.name === "unistyles") { %>
9
+ const { theme } = useUnistyles();
10
+ <% } %>
11
+ return (
12
+ <Tabs
13
+ screenOptions={{
14
+ headerShown: false,
15
+ <% if (props.stylingPackage?.name === "unistyles") { %>
16
+ tabBarActiveTintColor: theme.colors.astral,
17
+ tabBarStyle: {
18
+ backgroundColor: theme.colors.background,
19
+ }
20
+ <% } else { %>
21
+ tabBarActiveTintColor: 'black',
22
+ <% } %>
23
+ }}>
24
+ <Tabs.Screen
25
+ name="index"
26
+ options={{
27
+ title: 'Tab One',
28
+ tabBarIcon: ({ color }) => <TabBarIcon name="code" color={color} />,
29
+ }}
30
+ />
31
+ <Tabs.Screen
32
+ name="two"
33
+ options={{
34
+ title: 'Tab Two',
35
+ tabBarIcon: ({ color }) => <TabBarIcon name="code" color={color} />,
36
+ }}
37
+ />
38
+ </Tabs>
39
+ );
40
+ }
@@ -0,0 +1,15 @@
1
+ import { Stack } from 'expo-router';
2
+
3
+ import { Container } from '@/components/Container';
4
+ import { ScreenContent } from '@/components/ScreenContent';
5
+
6
+ export default function Home() {
7
+ return (
8
+ <>
9
+ <Stack.Screen options={{ title: 'Tab One' }} />
10
+ <Container>
11
+ <ScreenContent path="app/(drawer)/(tabs)/index.tsx" title="Tab One" />
12
+ </Container>
13
+ </>
14
+ );
15
+ }
@@ -0,0 +1,15 @@
1
+ import { Stack } from 'expo-router';
2
+
3
+ import { Container } from '@/components/Container';
4
+ import { ScreenContent } from '@/components/ScreenContent';
5
+
6
+ export default function Home() {
7
+ return (
8
+ <>
9
+ <Stack.Screen options={{ title: 'Tab Two' }} />
10
+ <Container>
11
+ <ScreenContent path="app/(drawer)/(tabs)/two.tsx" title="Tab Two" />
12
+ </Container>
13
+ </>
14
+ );
15
+ }