@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,73 @@
1
+ import { Stack, Link } from 'expo-router';
2
+ <% if (props.stylingPackage?.name === "stylesheet" || props.stylingPackage?.name === "restyle" || props.stylingPackage?.name === "tamagui") { %>
3
+ import { StyleSheet, View } from 'react-native';
4
+ <% } else if (props.stylingPackage?.name === "unistyles") { %>
5
+ import { StyleSheet } from 'react-native-unistyles';
6
+ import { View } from 'react-native';
7
+ <% } else { %>
8
+ import { View } from 'react-native';
9
+ <% } %>
10
+
11
+ import { Button } from '@/components/Button';
12
+ import { Container } from '@/components/Container';
13
+ import { ScreenContent } from '@/components/ScreenContent';
14
+
15
+ <% if (props.internalizationPackage?.name === "i18next") { %>
16
+ import { InternalizationExample } from 'components/InternalizationExample';
17
+ <% } %>
18
+
19
+ export default function Home() {
20
+ return (
21
+ <% if (props.stylingPackage?.name === "nativewind" || props.stylingPackage?.name === "uniwind") { %>
22
+ <View className={styles.container}>
23
+ <% } else { %>
24
+ <View style={styles.container}>
25
+ <% } %>
26
+ <Stack.Screen options={{ title: 'Home' }} />
27
+ <Container>
28
+ <ScreenContent path="app/index.tsx" title="Home">
29
+ <% if (props.internalizationPackage?.name === "i18next") { %>
30
+ <InternalizationExample />
31
+ <% } %>
32
+ </ScreenContent>
33
+ <Link href={{ pathname: '/details', params: { name: 'Dan' } }} asChild>
34
+ <% if (props.stylingPackage?.name === "unistyles") { %>
35
+ <Button title="Show Details" style={styles.button} />
36
+ <% } else { %>
37
+ <Button title="Show Details" />
38
+ <% } %>
39
+ </Link>
40
+ </Container>
41
+ </View>
42
+ );
43
+ }
44
+
45
+ <% if (props.stylingPackage?.name === "nativewind" || props.stylingPackage?.name === "uniwind") { %>
46
+ const styles = {
47
+ container: "flex flex-1 bg-white",
48
+ }
49
+ <% } else if (props.stylingPackage?.name === "restyle" || props.stylingPackage?.name === "tamagui") { %>
50
+ const styles = StyleSheet.create({
51
+ container: {
52
+ flex: 1,
53
+ backgroundColor: 'white',
54
+ },
55
+ });
56
+ <% } else if (props.stylingPackage?.name === "stylesheet") { %>
57
+ const styles = StyleSheet.create({
58
+ container: {
59
+ flex: 1,
60
+ backgroundColor: 'white',
61
+ },
62
+ });
63
+ <% } else if (props.stylingPackage?.name === "unistyles") { %>
64
+ const styles = StyleSheet.create((theme) => ({
65
+ container: {
66
+ flex: 1,
67
+ backgroundColor: 'white',
68
+ },
69
+ button: {
70
+ marginHorizontal: theme.margins.xl,
71
+ },
72
+ }));
73
+ <% } %>
@@ -0,0 +1,52 @@
1
+ import { Link, Tabs } from "expo-router";
2
+ <% if (props.stylingPackage?.name === "unistyles") { %>
3
+ import { useUnistyles } from "react-native-unistyles";
4
+ <% } %>
5
+ import { HeaderButton } from '../../components/HeaderButton';
6
+ import { TabBarIcon } from '../../components/TabBarIcon';
7
+
8
+ export default function TabLayout() {
9
+ <% if (props.stylingPackage?.name === "unistyles") { %>
10
+ const { theme } = useUnistyles();
11
+ <% } %>
12
+ return (
13
+ <Tabs
14
+ screenOptions={{
15
+ <% if (props.stylingPackage?.name === "unistyles") { %>
16
+ headerStyle: {
17
+ backgroundColor: theme.colors.background,
18
+ },
19
+ headerTitleStyle: {
20
+ color: theme.colors.typography,
21
+ },
22
+ tabBarActiveTintColor: theme.colors.astral,
23
+ tabBarStyle: {
24
+ backgroundColor: theme.colors.background,
25
+ },
26
+ <% } else { %>
27
+ tabBarActiveTintColor: 'black',
28
+ <% } %>
29
+ }}>
30
+ <Tabs.Screen
31
+ name='index'
32
+ options={{
33
+ title: 'Tab One',
34
+ tabBarIcon: ({ color }) => <TabBarIcon name="code" color={color} />,
35
+ headerRight: () => (
36
+ <Link href='/modal' asChild>
37
+ <HeaderButton />
38
+ </Link>
39
+ ),
40
+ }}
41
+ />
42
+ <Tabs.Screen
43
+ name="two"
44
+ options={{
45
+ title: 'Tab Two',
46
+ tabBarIcon: ({ color }) => <TabBarIcon name="code" color={color} />,
47
+ }}
48
+ />
49
+ </Tabs>
50
+ );
51
+ }
52
+
@@ -0,0 +1,37 @@
1
+ import { Stack } from 'expo-router';
2
+ <% if (props.stylingPackage?.name === 'unistyles') { %>
3
+ import { View } from 'react-native';
4
+ import { StyleSheet } from 'react-native-unistyles';
5
+ <% } else { %>
6
+ import { StyleSheet, View } from 'react-native';
7
+ <% } %>
8
+
9
+ import { ScreenContent } from '@/components/ScreenContent';
10
+
11
+ export default function Home() {
12
+ return (
13
+ <>
14
+ <Stack.Screen options={{ title: 'Tab One' }} />
15
+ <View style={styles.container}>
16
+ <ScreenContent path="app/(tabs)/index.tsx" title="Tab One" />
17
+ </View>
18
+ </>
19
+ );
20
+ }
21
+
22
+ <% if (props.stylingPackage?.name === 'unistyles') { %>
23
+ const styles = StyleSheet.create(theme => ({
24
+ container: {
25
+ flex: 1,
26
+ padding: 24,
27
+ backgroundColor: theme.colors.background,
28
+ },
29
+ }));
30
+ <% } else { %>
31
+ const styles = StyleSheet.create({
32
+ container: {
33
+ flex: 1,
34
+ padding: 24,
35
+ },
36
+ });
37
+ <% } %>
@@ -0,0 +1,37 @@
1
+ import { Stack } from 'expo-router';
2
+ <% if (props.stylingPackage?.name === 'unistyles') { %>
3
+ import { View } from 'react-native';
4
+ import { StyleSheet } from 'react-native-unistyles';
5
+ <% } else { %>
6
+ import { StyleSheet, View } from 'react-native';
7
+ <% } %>
8
+
9
+ import { ScreenContent } from '@/components/ScreenContent';
10
+
11
+ export default function Home() {
12
+ return (
13
+ <>
14
+ <Stack.Screen options={{ title: 'Tab Two' }} />
15
+ <View style={styles.container}>
16
+ <ScreenContent path="app/(tabs)/two.tsx" title="Tab Two" />
17
+ </View>
18
+ </>
19
+ );
20
+ }
21
+
22
+ <% if (props.stylingPackage?.name === 'unistyles') { %>
23
+ const styles = StyleSheet.create(theme => ({
24
+ container: {
25
+ flex: 1,
26
+ padding: 24,
27
+ backgroundColor: theme.colors.background,
28
+ },
29
+ }));
30
+ <% } else { %>
31
+ const styles = StyleSheet.create({
32
+ container: {
33
+ flex: 1,
34
+ padding: 24,
35
+ },
36
+ });
37
+ <% } %>
@@ -0,0 +1,49 @@
1
+ import { ScrollViewStyleReset } from 'expo-router/html';
2
+ <% if (props.stylingPackage?.name === "unistyles") { %>
3
+ import '../unistyles';
4
+ <% } %>
5
+
6
+ // This file is web-only and used to configure the root HTML for every
7
+ // web page during static rendering.
8
+ // The contents of this function only run in Node.js environments and
9
+ // do not have access to the DOM or browser APIs.
10
+ export default function Root({ children }: { children: React.ReactNode }) {
11
+ return (
12
+ <html lang="en">
13
+ <head>
14
+ <meta charSet="utf-8" />
15
+ <meta httpEquiv="X-UA-Compatible" content="IE=edge" />
16
+
17
+ {/*
18
+ This viewport disables scaling which makes the mobile website act more like a native app.
19
+ However this does reduce built-in accessibility. If you want to enable scaling, use this instead:
20
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
21
+ */}
22
+ <meta
23
+ name="viewport"
24
+ content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1.00001,viewport-fit=cover"
25
+ />
26
+ {/*
27
+ Disable body scrolling on web. This makes ScrollView components work closer to how they do on native.
28
+ However, body scrolling is often nice to have for mobile web. If you want to enable it, remove this line.
29
+ */}
30
+ <ScrollViewStyleReset />
31
+
32
+ {/* Using raw CSS styles as an escape-hatch to ensure the background color never flickers in dark-mode. */}
33
+ <style dangerouslySetInnerHTML={{ __html: responsiveBackground }} />
34
+ {/* Add any additional <head> elements that you want globally available on web... */}
35
+ </head>
36
+ <body>{children}</body>
37
+ </html>
38
+ );
39
+ }
40
+
41
+ const responsiveBackground = `
42
+ body {
43
+ background-color: #fff;
44
+ }
45
+ @media (prefers-color-scheme: dark) {
46
+ body {
47
+ background-color: #000;
48
+ }
49
+ }`;
@@ -0,0 +1,110 @@
1
+ import { Link, Stack } from 'expo-router';
2
+ <% if (props.stylingPackage?.name === "nativewind" || props.stylingPackage?.name === "uniwind") {%>
3
+ import { Text, View } from 'react-native';
4
+ <% } else if (props.stylingPackage?.name === "restyle" || props.stylingPackage?.name === "tamagui") { %>
5
+ import { StyleSheet, Text, View } from 'react-native';
6
+ <% } else if (props.stylingPackage?.name === "unistyles") { %>
7
+ import { StyleSheet } from 'react-native-unistyles'
8
+ import { Text, View } from 'react-native';
9
+ <% } else if (props.stylingPackage?.name === "stylesheet") { %>
10
+ import { StyleSheet, Text, View } from 'react-native';
11
+ <% } %>
12
+
13
+ export default function NotFoundScreen() {
14
+
15
+ return (
16
+ <% if (props.stylingPackage?.name === "nativewind" || props.stylingPackage?.name === "uniwind") {%>
17
+ <>
18
+ <Stack.Screen options={{ title: "Oops!" }} />
19
+ <View className={styles.container}>
20
+ <Text className={styles.title}>{"This screen doesn't exist."}</Text>
21
+ <Link href="/" className={styles.link}>
22
+ <Text className={styles.linkText}>Go to home screen!</Text>
23
+ </Link>
24
+ </View>
25
+ </>
26
+ <% } else { %>
27
+ <>
28
+ <Stack.Screen options={{ title: "Oops!" }} />
29
+ <View style={styles.container}>
30
+ <Text style={styles.title}>{"This screen doesn't exist."}</Text>
31
+ <Link href="/" style={styles.link}>
32
+ <Text style={styles.linkText}>Go to home screen!</Text>
33
+ </Link>
34
+ </View>
35
+ </>
36
+ <% } %>
37
+ );
38
+ }
39
+
40
+ <% if (props.stylingPackage?.name === "nativewind" || props.stylingPackage?.name === "uniwind") { %>
41
+ const styles = {
42
+ container: `items-center flex-1 justify-center p-5`,
43
+ title: `text-xl font-bold`,
44
+ link: `mt-4 pt-4`,
45
+ linkText: `text-base text-[#2e78b7]`,
46
+ };
47
+ <% } else if (props.stylingPackage?.name === "unistyles") { %>
48
+ const styles = StyleSheet.create((theme) => ({
49
+ container: {
50
+ flex: 1,
51
+ alignItems: 'center',
52
+ justifyContent: 'center',
53
+ padding: 20,
54
+ },
55
+ title: {
56
+ fontSize: 20,
57
+ fontWeight: 'bold',
58
+ },
59
+ link: {
60
+ marginTop: 16,
61
+ paddingVertical: 16,
62
+ },
63
+ linkText: {
64
+ fontSize: 14,
65
+ color: theme.colors.astral,
66
+ },
67
+ }));
68
+ <% } else if (props.stylingPackage?.name === "restyle" || props.stylingPackage?.name === "tamagui") { %>
69
+ const styles = StyleSheet.create({
70
+ container: {
71
+ flex: 1,
72
+ alignItems: 'center',
73
+ justifyContent: 'center',
74
+ padding: 20,
75
+ },
76
+ title: {
77
+ fontSize: 20,
78
+ fontWeight: 'bold',
79
+ },
80
+ link: {
81
+ marginTop: 16,
82
+ paddingVertical: 16,
83
+ },
84
+ linkText: {
85
+ fontSize: 14,
86
+ color: '#2e78b7',
87
+ },
88
+ });
89
+ <% } else if (props.stylingPackage?.name === "stylesheet") { %>
90
+ const styles = StyleSheet.create({
91
+ container: {
92
+ flex: 1,
93
+ alignItems: 'center',
94
+ justifyContent: 'center',
95
+ padding: 20,
96
+ },
97
+ title: {
98
+ fontSize: 20,
99
+ fontWeight: 'bold',
100
+ },
101
+ link: {
102
+ marginTop: 16,
103
+ paddingVertical: 16,
104
+ },
105
+ linkText: {
106
+ fontSize: 14,
107
+ color: '#2e78b7',
108
+ },
109
+ });
110
+ <% } %>
@@ -0,0 +1,84 @@
1
+ <% if (props.stylingPackage?.name === "nativewind" || props.stylingPackage?.name === "uniwind") { %>
2
+ import '../global.css';
3
+ import { SafeAreaProvider } from 'react-native-safe-area-context';
4
+ <% } else if (props.stylingPackage?.name === "nativewindui") { %>
5
+ import '../global.css';
6
+ import 'expo-dev-client';
7
+ <% } else if (props.stylingPackage?.name === "unistyles") { %>
8
+ import { useUnistyles } from "react-native-unistyles";
9
+ <% } else if (props.stylingPackage?.name === "restyle") { %>
10
+ import { ThemeProvider } from '@shopify/restyle';
11
+ import { theme } from '../theme';
12
+ <% } else if (props.stylingPackage?.name === "tamagui") { %>
13
+ import { TamaguiProvider } from 'tamagui';
14
+ import config from '../tamagui.config';
15
+ <% } %>
16
+ <% if (props.internalizationPackage?.name === "i18next") { %>
17
+ import '../translation';
18
+ <% } %>
19
+ import { Stack } from "expo-router";
20
+
21
+ <% if (props.analyticsPackage?.name === "vexo-analytics") { %>
22
+ import { vexo } from 'vexo-analytics';
23
+
24
+ const vexoApiKey = process.env.EXPO_PUBLIC_VEXO_API_KEY;
25
+ if (vexoApiKey) {
26
+ vexo(vexoApiKey);
27
+ }
28
+ <% } %>
29
+
30
+ export const unstable_settings = {
31
+ // Ensure that reloading on `/modal` keeps a back button present.
32
+ initialRouteName: "(tabs)",
33
+ };
34
+
35
+ export default function RootLayout() {
36
+ <% if (props.stylingPackage?.name === "unistyles") { %>
37
+ const { theme } = useUnistyles();
38
+ <% } %>
39
+
40
+ return (
41
+ <% if (props.stylingPackage?.name === "restyle") { %>
42
+ <ThemeProvider theme={theme}>
43
+ <Stack>
44
+ <Stack.Screen name="(tabs)" options={{ headerShown: false }} />
45
+ <Stack.Screen name="modal" options={{ presentation: "modal" }} />
46
+ </Stack>
47
+ </ThemeProvider>
48
+ <% } else if (props.stylingPackage?.name === "tamagui") { %>
49
+ <TamaguiProvider config={config}>
50
+ <Stack>
51
+ <Stack.Screen name="(tabs)" options={{ headerShown: false }} />
52
+ <Stack.Screen name="modal" options={{ presentation: "modal" }} />
53
+ </Stack>
54
+ </TamaguiProvider>
55
+ <% } else if (props.stylingPackage?.name === "nativewind" || props.stylingPackage?.name === "uniwind") { %>
56
+ <SafeAreaProvider>
57
+ <Stack>
58
+ <Stack.Screen name="(tabs)" options={{ headerShown: false }} />
59
+ <Stack.Screen name="modal" options={{ presentation: "modal" }} />
60
+ </Stack>
61
+ </SafeAreaProvider>
62
+ <% } else if (props.stylingPackage?.name === "unistyles") { %>
63
+ <Stack
64
+ screenOptions={{
65
+ headerStyle: {
66
+ backgroundColor: theme.colors.background,
67
+ },
68
+ headerTitleStyle: {
69
+ color: theme.colors.typography,
70
+ },
71
+ headerTintColor: theme.colors.typography
72
+ }}
73
+ >
74
+ <Stack.Screen name="(tabs)" options={{ headerShown: false }} />
75
+ <Stack.Screen name="modal" options={{ presentation: "modal" }} />
76
+ </Stack>
77
+ <% } else { %>
78
+ <Stack>
79
+ <Stack.Screen name="(tabs)" options={{ headerShown: false }} />
80
+ <Stack.Screen name="modal" options={{ presentation: "modal" }} />
81
+ </Stack>
82
+ <% } %>
83
+ );
84
+ }
@@ -0,0 +1,21 @@
1
+ import { StatusBar } from 'expo-status-bar';
2
+ import { Platform } from 'react-native';
3
+
4
+ import { ScreenContent } from '@/components/ScreenContent';
5
+
6
+ <% if (props.internalizationPackage?.name === "i18next") { %>
7
+ import { InternalizationExample } from 'components/InternalizationExample';
8
+ <% } %>
9
+
10
+ export default function Modal() {
11
+ return (
12
+ <>
13
+ <ScreenContent path="app/modal.tsx" title="Modal">
14
+ <% if (props.internalizationPackage?.name === "i18next") { %>
15
+ <InternalizationExample />
16
+ <% } %>
17
+ </ScreenContent>
18
+ <StatusBar style={Platform.OS === 'ios' ? 'light' : 'auto'} />
19
+ </>
20
+ );
21
+ }
@@ -0,0 +1,8 @@
1
+ EXPO_PUBLIC_FIREBASE_API_KEY=api_key
2
+ EXPO_PUBLIC_FIREBASE_AUTH_DOMAIN=project-id.firebaseapp.com
3
+ EXPO_PUBLIC_DATABASE_URL=https://project-id.firebaseio.com
4
+ EXPO_PUBLIC_PROJECT_ID=project-id
5
+ EXPO_PUBLIC_STORAGE_BUCKET=project-id.appspot.com
6
+ EXPO_PUBLIC_MESSAGING_SENDER_ID=sender-id
7
+ EXPO_PUBLIC_APP_ID=app-id
8
+ EXPO_PUBLIC_MEASUREMENT_ID=G-measurement-id
@@ -0,0 +1,14 @@
1
+ const { getDefaultConfig } = require('expo/metro-config');
2
+ <% if (props.stylingPackage?.name === "nativewind") { %>
3
+ const { withNativeWind } = require("nativewind/metro");
4
+ <% } %>
5
+
6
+ /** @type {import('expo/metro-config').MetroConfig} */
7
+ // eslint-disable-next-line no-undef
8
+ const config = getDefaultConfig(__dirname);
9
+
10
+ <% if (props.stylingPackage?.name === "nativewind") { %>
11
+ module.exports = withNativeWind(config, { input: "./global.css" });
12
+ <% } else { %>
13
+ module.exports = config;
14
+ <% } %>
@@ -0,0 +1,26 @@
1
+ import { initializeApp } from 'firebase/app';
2
+
3
+ // Optionally import the services that you want to use
4
+ // import {...} from "firebase/auth";
5
+ // import {...} from "firebase/database";
6
+ // import {...} from "firebase/firestore";
7
+ // import {...} from "firebase/functions";
8
+ // import {...} from "firebase/storage";
9
+
10
+ // Initialize Firebase
11
+ const firebaseConfig = {
12
+ apiKey: process.env.EXPO_PUBLIC_FIREBASE_API_KEY,
13
+ authDomain: process.env.EXPO_PUBLIC_FIREBASE_AUTH_DOMAIN,
14
+ databaseURL: process.env.EXPO_PUBLIC_FIREBASE_DATABASE_URL,
15
+ projectId: process.env.EXPO_PUBLIC_PROJECT_ID,
16
+ storageBucket: process.env.EXPO_PUBLIC_FIREBASE_STORAGE_BUCKET,
17
+ messagingSenderId: process.env.EXPO_PUBLIC_FIREBASE_MESSAGING_SENDER_ID,
18
+ appId: process.env.EXPO_PUBLIC_FIREBASE_APP_ID,
19
+ measurementId: process.env.EXPO_PUBLIC_FIREBASE_MEASUREMENT_ID,
20
+ };
21
+
22
+ const firebase = initializeApp(firebaseConfig);
23
+ // For more information on how to access Firebase in your project,
24
+ // see the Firebase documentation: https://firebase.google.com/docs/web/setup#access-firebase
25
+
26
+ export default firebase;
@@ -0,0 +1,23 @@
1
+ import React from 'react';
2
+ import { useTranslation } from 'react-i18next';
3
+ import { Button, StyleSheet, View } from 'react-native';
4
+
5
+ export const InternalizationExample = () => {
6
+ const { t, i18n } = useTranslation();
7
+
8
+ const toggleLanguage = (locale: 'en' | 'fr') => {
9
+ i18n.changeLanguage(locale);
10
+ };
11
+ return (
12
+ <>
13
+ <View style={styles.content}>
14
+ <Button title={t('button.french')} onPress={() => toggleLanguage('fr')} />
15
+ <Button title={t('button.english')} onPress={() => toggleLanguage('en')} />
16
+ </View>
17
+ </>
18
+ );
19
+ };
20
+
21
+ export const styles = StyleSheet.create({
22
+ content: { gap: 20, padding: 20 },
23
+ });
@@ -0,0 +1,13 @@
1
+ import { Resource } from 'i18next';
2
+
3
+ export const fallbackChecker = (resources: Resource, fallbackLng: string) => {
4
+ const languages = Object.keys(resources);
5
+ const hasFallback = languages.find((key) => fallbackLng === key);
6
+
7
+ if (!hasFallback) {
8
+ throw new Error(
9
+ `fallbackLng "${fallbackLng}", is not present in your resources, please check your config, languages available: ${languages.join(', ')}`
10
+ );
11
+ }
12
+ return fallbackLng;
13
+ };
@@ -0,0 +1,24 @@
1
+ import i18n, { Resource } from 'i18next';
2
+ import { initReactI18next } from 'react-i18next';
3
+
4
+ import { fallbackChecker } from './fallbackChecker';
5
+ import { languageDetector } from './languageDetector';
6
+
7
+ type Init18n = {
8
+ resources: Resource;
9
+ fallbackLng: string;
10
+ };
11
+
12
+ export const init18n = ({ resources, fallbackLng }: Init18n) => {
13
+ return i18n
14
+ .use(languageDetector)
15
+ .use(initReactI18next)
16
+ .init({
17
+ resources,
18
+ fallbackLng: fallbackChecker(resources, fallbackLng),
19
+ compatibilityJSON: 'v3', // By default React Native projects does not support Intl
20
+ interpolation: {
21
+ escapeValue: false,
22
+ },
23
+ });
24
+ };
@@ -0,0 +1,13 @@
1
+ import * as Localization from 'expo-localization';
2
+ import { LanguageDetectorModule } from 'i18next';
3
+
4
+ export const languageDetector: LanguageDetectorModule = {
5
+ type: 'languageDetector',
6
+ detect: () => {
7
+ const locales = Localization.getLocales();
8
+ const firstLanguageCode = locales[0].languageCode ?? 'en';
9
+ return firstLanguageCode;
10
+ },
11
+ init: () => {},
12
+ cacheUserLanguage: () => {},
13
+ };
@@ -0,0 +1,8 @@
1
+ {
2
+ "button": {
3
+ "french": "Switch language to French",
4
+ "english": "Switch language to English"
5
+ },
6
+ "getStarted": "Open up the code for this screen:",
7
+ "changeCode": "Change any of the text, save the file, and your app will automatically update."
8
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "button": {
3
+ "french": "Changer la langue en français",
4
+ "english": "Changer la langue en anglais"
5
+ },
6
+ "getStarted": "Ouvrez le code de cet écran :",
7
+ "changeCode": "Modifiez n'importe quel texte, enregistrez le fichier et votre application sera automatiquement mise à jour."
8
+ }
@@ -0,0 +1,20 @@
1
+ import { init18n } from 'core/i18n/init';
2
+ import en from 'translation/en.json';
3
+ import fr from 'translation/fr.json';
4
+
5
+ export const resources = {
6
+ en: {
7
+ translation: en,
8
+ },
9
+ fr: {
10
+ translation: fr,
11
+ },
12
+ };
13
+
14
+ export const fallbackLng = 'en';
15
+
16
+ export type LanguageCode = keyof typeof resources;
17
+
18
+ const i18n = init18n({ resources, fallbackLng });
19
+
20
+ export default i18n;
@@ -0,0 +1,22 @@
1
+ import { Feather } from '@expo/vector-icons';
2
+ import { Text, View } from 'react-native';
3
+
4
+ interface BackButtonProps {
5
+ onPress: () => void;
6
+ }
7
+
8
+ export const BackButton: React.FC<BackButtonProps> = ({ onPress }) => {
9
+ return (
10
+ <View className={styles.backButton}>
11
+ <Feather name="chevron-left" size={16} color="#007AFF" />
12
+ <Text className={styles.backButtonText} onPress={onPress}>
13
+ Back
14
+ </Text>
15
+ </View>
16
+ );
17
+ };
18
+
19
+ const styles = {
20
+ backButton: 'flex-row',
21
+ backButtonText: 'text-blue-500 ml-1',
22
+ };