From ab447b1a3c778ef4972887b9880d9a39462e1a04 Mon Sep 17 00:00:00 2001 From: mickeypause Date: Mon, 30 Sep 2024 09:02:59 +0300 Subject: [PATCH 1/4] add redux --- .changeset/thin-wolves-push.md | 5 + cli/src/commands/create-expo-stack.ts | 15 +- cli/src/templates/base/App.tsx.ejs | 131 ++++++++++-------- cli/src/templates/base/package.json.ejs | 5 + .../expo-router/drawer/app/_layout.tsx.ejs | 103 ++++++++------ .../expo-router/stack/app/_layout.tsx.ejs | 91 ++++++------ .../expo-router/tabs/app/_layout.tsx.ejs | 104 ++++++++------ .../packages/react-navigation/App.tsx.ejs | 114 +++++++++------ .../redux/store/reducers/demoSlice.ts.ejs | 23 +++ .../packages/redux/store/store.ts.ejs | 23 +++ cli/src/types.ts | 7 +- cli/src/utilities/configureProjectFiles.ts | 10 +- cli/src/utilities/generateProjectFiles.ts | 10 +- cli/src/utilities/runCLI.ts | 21 ++- 14 files changed, 424 insertions(+), 238 deletions(-) create mode 100644 .changeset/thin-wolves-push.md create mode 100644 cli/src/templates/packages/redux/store/reducers/demoSlice.ts.ejs create mode 100644 cli/src/templates/packages/redux/store/store.ts.ejs diff --git a/.changeset/thin-wolves-push.md b/.changeset/thin-wolves-push.md new file mode 100644 index 00000000..56bbea77 --- /dev/null +++ b/.changeset/thin-wolves-push.md @@ -0,0 +1,5 @@ +--- +'create-expo-stack': minor +--- + +add redux diff --git a/cli/src/commands/create-expo-stack.ts b/cli/src/commands/create-expo-stack.ts index 16e14522..0cf59787 100644 --- a/cli/src/commands/create-expo-stack.ts +++ b/cli/src/commands/create-expo-stack.ts @@ -309,6 +309,14 @@ const command: GluegunCommand = { cliResults.packages.push({ name: 'vexo-analytics', type: 'analytics' }); } + if (options.redux) { + // Add redux package + cliResults.packages.push({ + name: 'redux', + type: 'state-management' + }); + } + // By this point, all cliResults should be set info(''); highlight('Your project configuration:'); @@ -407,6 +415,7 @@ const command: GluegunCommand = { const stylingPackage = packages.find((p) => p.type === 'styling'); const internalizationPackage = packages.find((p) => p.type === 'internationalization'); const analyticsPackage = packages.find((p) => p.type === 'analytics'); + const stateManagementPackage = packages.find((p) => p.type === 'state-management') || undefined; let files: string[] = []; @@ -418,7 +427,8 @@ const command: GluegunCommand = { analyticsPackage, toolbox, cliResults, - internalizationPackage + internalizationPackage, + stateManagementPackage ); // Once all the files are defined, format and generate them @@ -434,7 +444,8 @@ const command: GluegunCommand = { packageManager, stylingPackage, toolbox, - internalizationPackage + internalizationPackage, + stateManagementPackage ); await printOutput(cliResults, formattedFiles, toolbox, stylingPackage); diff --git a/cli/src/templates/base/App.tsx.ejs b/cli/src/templates/base/App.tsx.ejs index 112a2feb..03036309 100644 --- a/cli/src/templates/base/App.tsx.ejs +++ b/cli/src/templates/base/App.tsx.ejs @@ -2,72 +2,95 @@ import { ScreenContent } from 'components/ScreenContent'; import { StatusBar } from 'expo-status-bar'; <% if (props.internalizationPackage?.name === "i18next") { %> - import './translation'; - import { InternalizationExample } from 'components/InternalizationExample'; +import './translation'; +import { InternalizationExample } from 'components/InternalizationExample'; <% } %> <% if (props.stylingPackage?.name === "nativewind") { %> - import './global.css'; +import './global.css'; <% } else if (props.stylingPackage?.name === "nativewinui") { %> - import './global.css'; - import 'expo-dev-client'; +import './global.css'; +import 'expo-dev-client'; <% } else if (props.stylingPackage?.name === "restyle") { %> - import { ThemeProvider } from '@shopify/restyle'; - import { theme } from 'theme'; +import { ThemeProvider } from '@shopify/restyle'; +import { theme } from 'theme'; <% } else if (props.stylingPackage?.name === "tamagui") { %> - <% if (!props.internalizationPackage) { %> - import { Text } from 'react-native'; - <% } %> - import { TamaguiProvider } from 'tamagui'; - import config from './tamagui.config'; +<% if (!props.internalizationPackage) { %> +import { Text } from 'react-native'; +<% } %> +import { TamaguiProvider } from 'tamagui'; +import config from './tamagui.config'; <% } %> <% if (props.analyticsPackage?.name === "vexo-analytics") { %> - import { vexo } from 'vexo-analytics'; +import { vexo } from 'vexo-analytics'; - vexo(process.env.EXPO_PUBLIC_VEXO_API_KEY); +vexo(process.env.EXPO_PUBLIC_VEXO_API_KEY); <% } %> +<% if (props.stateManagementPackage?.name === "redux") { %> +import { Provider } from 'react-redux' +import store from 'store/store' +<% } %> + + <% if (props.stylingPackage?.name === "restyle") {%> - export default function App() { - return ( - - - <% if (props.internalizationPackage?.name === "i18next") { %> - - <% } %> - - - - ); - } +export default function App() { +return ( + + <% if (props.stateManagementPackage?.name === "redux") { %> + + <% } %> + + <% if (props.internalizationPackage?.name === "i18next") { %> + + <% } %> + + <% if (props.stateManagementPackage?.name === "redux") { %> + + <% } %> + + +); +} <% } else if (props.stylingPackage?.name === "tamagui") {%> - export default function App() { - return ( - - - <% if (props.internalizationPackage?.name === "i18next") { %> - - <% } else { %> - Open up App.tsx to start working on your app! - <% } %> - - - - ); - } +export default function App() { +return ( + + <% if (props.stateManagementPackage?.name === "redux") { %> + + <% } %> + + <% if (props.internalizationPackage?.name === "i18next") { %> + + <% } else { %> + Open up App.tsx to start working on your app! + <% } %> + + <% if (props.stateManagementPackage?.name === "redux") { %> + + <% } %> + + +); +} <% } else { %> - export default function App() { - return ( - <> - - <% if (props.internalizationPackage?.name === "i18next") { %> - - <% } %> - - - - ); - } -<% } %> - +export default function App() { +return ( +<> + <% if (props.stateManagementPackage?.name === "redux") { %> + + <% } %> + + <% if (props.internalizationPackage?.name === "i18next") { %> + + <% } %> + + <% if (props.stateManagementPackage?.name === "redux") { %> + + <% } %> + + +); +} +<% } %> \ No newline at end of file diff --git a/cli/src/templates/base/package.json.ejs b/cli/src/templates/base/package.json.ejs index 9ff1e063..6b5cb6a2 100644 --- a/cli/src/templates/base/package.json.ejs +++ b/cli/src/templates/base/package.json.ejs @@ -93,6 +93,11 @@ "vexo-analytics": "^1.3.15", <% } %> + <% if (props.stateManagementPackage?.name === "redux") { %> + "react-redux": "^9.1.2", + "@reduxjs/toolkit": "^2.2.7", + <% } %> + <% if ((props.navigationPackage?.name === "react-navigation") && (props.stylingPackage?.name === "tamagui")) { %> "expo-splash-screen": "~0.27.4", <% } %> diff --git a/cli/src/templates/packages/expo-router/drawer/app/_layout.tsx.ejs b/cli/src/templates/packages/expo-router/drawer/app/_layout.tsx.ejs index c5bf2d2a..fd4b7af9 100644 --- a/cli/src/templates/packages/expo-router/drawer/app/_layout.tsx.ejs +++ b/cli/src/templates/packages/expo-router/drawer/app/_layout.tsx.ejs @@ -1,15 +1,15 @@ <% if (props.stylingPackage?.name === "nativewind") { %> - import '../global.css'; +import '../global.css'; <% } else if (props.stylingPackage?.name === "nativewinui") { %> - import '../global.css'; - import 'expo-dev-client'; +import '../global.css'; +import 'expo-dev-client'; <% } %> <% if (props.stylingPackage?.name === "unistyles") { %> import '../unistyles'; <% } %> <% if (props.internalizationPackage?.name === "i18next") { %> - import '../translation'; +import '../translation'; <% } %> import 'react-native-gesture-handler'; @@ -17,63 +17,74 @@ import { GestureHandlerRootView } from 'react-native-gesture-handler'; import { Stack } from 'expo-router'; <% if (props.stylingPackage?.name==="tamagui" ) { %> - import React, { useEffect } from "react"; - import { TamaguiProvider } from 'tamagui' - import { SplashScreen } from "expo-router"; - import { useFonts } from "expo-font"; +import React, { useEffect } from "react"; +import { TamaguiProvider } from 'tamagui' +import { SplashScreen } from "expo-router"; +import { useFonts } from "expo-font"; - import config from '../tamagui.config'; +import config from '../tamagui.config'; - SplashScreen.preventAutoHideAsync(); +SplashScreen.preventAutoHideAsync(); <% } else if (props.stylingPackage?.name === "restyle") { %> - import { ThemeProvider } from '@shopify/restyle'; - - import { theme } from '../theme'; +import { ThemeProvider } from '@shopify/restyle'; + +import { theme } from '../theme'; <% } %> <% if (props.analyticsPackage?.name === "vexo-analytics") { %> - import { vexo } from 'vexo-analytics'; +import { vexo } from 'vexo-analytics'; - vexo(process.env.EXPO_PUBLIC_VEXO_API_KEY); +vexo(process.env.EXPO_PUBLIC_VEXO_API_KEY); +<% } %> +<% if (props.stateManagementPackage?.name === "redux") { %> +import { Provider } from 'react-redux' +import store from 'store/store' <% } %> + export const unstable_settings = { - // Ensure that reloading on `/modal` keeps a back button present. - initialRouteName: "(drawer)", +// Ensure that reloading on `/modal` keeps a back button present. +initialRouteName: "(drawer)", }; export default function RootLayout() { - <% if (props.stylingPackage?.name==="tamagui" ) { %> - const [loaded] = useFonts({ - Inter: require("@tamagui/font-inter/otf/Inter-Medium.otf"), - InterBold: require("@tamagui/font-inter/otf/Inter-Bold.otf") - }); +<% if (props.stylingPackage?.name==="tamagui" ) { %> +const [loaded] = useFonts({ +Inter: require("@tamagui/font-inter/otf/Inter-Medium.otf"), +InterBold: require("@tamagui/font-inter/otf/Inter-Bold.otf") +}); - useEffect(() => { - if (loaded) { - SplashScreen.hideAsync(); - } - }, [loaded]); +useEffect(() => { +if (loaded) { +SplashScreen.hideAsync(); +} +}, [loaded]); - if (!loaded) return null; - <% } %> +if (!loaded) return null; +<% } %> - return ( - <% if (props.stylingPackage?.name === "tamagui") { %> - - <% } else if (props.stylingPackage?.name === "restyle") { %> - - <% } %> - - - - - - - <% if (props.stylingPackage?.name === "tamagui") { %> - - <% } else if (props.stylingPackage?.name === "restyle") { %> - +return ( +<% if (props.stylingPackage?.name === "tamagui") { %> + + <% } else if (props.stylingPackage?.name === "restyle") { %> + + <% } %> + + <% if (props.stateManagementPackage?.name === "redux") { %> + + <% } %> + + + + + <% if (props.stateManagementPackage?.name === "redux") { %> + <% } %> - ); + + <% if (props.stylingPackage?.name === "tamagui") { %> + +<% } else if (props.stylingPackage?.name === "restyle") { %> + +<% } %> +); } \ No newline at end of file diff --git a/cli/src/templates/packages/expo-router/stack/app/_layout.tsx.ejs b/cli/src/templates/packages/expo-router/stack/app/_layout.tsx.ejs index 5220239c..b337d0c0 100644 --- a/cli/src/templates/packages/expo-router/stack/app/_layout.tsx.ejs +++ b/cli/src/templates/packages/expo-router/stack/app/_layout.tsx.ejs @@ -1,61 +1,72 @@ <% if (props.stylingPackage?.name === "nativewind") { %> - import '../global.css'; +import '../global.css'; <% } %> <% if (props.stylingPackage?.name === "unistyles") { %> import '../unistyles'; <% } %> <% if (props.internalizationPackage?.name === "i18next") { %> - import '../translation'; +import '../translation'; <% } %> <% if (props.stylingPackage?.name === "tamagui") { %> - import { useFonts } from 'expo-font'; - import { SplashScreen, Stack } from 'expo-router'; - import { useEffect } from 'react'; - import { TamaguiProvider } from 'tamagui'; +import { useFonts } from 'expo-font'; +import { SplashScreen, Stack } from 'expo-router'; +import { useEffect } from 'react'; +import { TamaguiProvider } from 'tamagui'; - import config from '../tamagui.config'; +import config from '../tamagui.config'; <% } else if (props.stylingPackage?.name === "restyle") { %> - import { ThemeProvider } from '@shopify/restyle'; - import { theme } from 'theme'; +import { ThemeProvider } from '@shopify/restyle'; +import { theme } from 'theme'; <% } %> - import { Stack } from "expo-router"; +import { Stack } from "expo-router"; <% if (props.analyticsPackage?.name === "vexo-analytics") { %> - import { vexo } from 'vexo-analytics'; +import { vexo } from 'vexo-analytics'; - vexo(process.env.EXPO_PUBLIC_VEXO_API_KEY); +vexo(process.env.EXPO_PUBLIC_VEXO_API_KEY); <% } %> +<% if (props.stateManagementPackage?.name === "redux") { %> +import { Provider } from 'react-redux' +import store from 'store/store' +<% } %> + export default function Layout() { - <% if (props.stylingPackage?.name === "tamagui") { %> - const [loaded] = useFonts({ - Inter: require("@tamagui/font-inter/otf/Inter-Medium.otf"), - InterBold: require("@tamagui/font-inter/otf/Inter-Bold.otf") - }); - - useEffect(() => { - if (loaded) { - SplashScreen.hideAsync(); - } - }, [loaded]); - - if (!loaded) return null; - <% } %> - - return ( - <% if (props.stylingPackage?.name === "tamagui") { %> - - <% } else if (props.stylingPackage?.name === "restyle") { %> - - <% } %> - - <% if (props.stylingPackage?.name === "tamagui") { %> - - <% } else if (props.stylingPackage?.name === "restyle") { %> - - <% } %> - ); +<% if (props.stylingPackage?.name === "tamagui") { %> +const [loaded] = useFonts({ +Inter: require("@tamagui/font-inter/otf/Inter-Medium.otf"), +InterBold: require("@tamagui/font-inter/otf/Inter-Bold.otf") +}); + +useEffect(() => { +if (loaded) { +SplashScreen.hideAsync(); } +}, [loaded]); + +if (!loaded) return null; +<% } %> + +return ( +<% if (props.stylingPackage?.name === "tamagui") { %> + + <% } else if (props.stylingPackage?.name === "restyle") { %> + + <% } %> + <% if (props.stateManagementPackage?.name === "redux") { %> + + <% } %> + + <% if (props.stateManagementPackage?.name === "redux") { %> + + <% } %> + <% if (props.stylingPackage?.name === "tamagui") { %> + +<% } else if (props.stylingPackage?.name === "restyle") { %> + +<% } %> +); +} \ No newline at end of file diff --git a/cli/src/templates/packages/expo-router/tabs/app/_layout.tsx.ejs b/cli/src/templates/packages/expo-router/tabs/app/_layout.tsx.ejs index 489ca9de..8c209caa 100644 --- a/cli/src/templates/packages/expo-router/tabs/app/_layout.tsx.ejs +++ b/cli/src/templates/packages/expo-router/tabs/app/_layout.tsx.ejs @@ -1,74 +1,86 @@ <% if (props.stylingPackage?.name === "nativewind") { %> - import '../global.css'; +import '../global.css'; <% } else if (props.stylingPackage?.name === "nativewinui") { %> - import '../global.css'; - import 'expo-dev-client'; +import '../global.css'; +import 'expo-dev-client'; <% } %> <% if (props.stylingPackage?.name === "unistyles") { %> import '../unistyles'; <% } %> <% if (props.internalizationPackage?.name === "i18next") { %> - import '../translation'; +import '../translation'; <% } %> <% if (props.stylingPackage?.name === "tamagui") { %> - import React, { useEffect } from "react"; - import { TamaguiProvider } from 'tamagui' - import { SplashScreen, Stack } from "expo-router"; - import { useFonts } from "expo-font"; +import React, { useEffect } from "react"; +import { TamaguiProvider } from 'tamagui' +import { SplashScreen, Stack } from "expo-router"; +import { useFonts } from "expo-font"; - import config from '../tamagui.config' +import config from '../tamagui.config' - SplashScreen.preventAutoHideAsync(); +SplashScreen.preventAutoHideAsync(); <% } else if (props.stylingPackage?.name === "restyle") { %> - import { ThemeProvider } from '@shopify/restyle'; - import { Stack } from 'expo-router'; - import { theme } from 'theme'; +import { ThemeProvider } from '@shopify/restyle'; +import { Stack } from 'expo-router'; +import { theme } from 'theme'; <% } else { %> - import { Stack } from "expo-router"; +import { Stack } from "expo-router"; <% } %> <% if (props.analyticsPackage?.name === "vexo-analytics") { %> - import { vexo } from 'vexo-analytics'; +import { vexo } from 'vexo-analytics'; - vexo(process.env.EXPO_PUBLIC_VEXO_API_KEY); +vexo(process.env.EXPO_PUBLIC_VEXO_API_KEY); <% } %> +<% if (props.stateManagementPackage?.name === "redux") { %> +import { Provider } from 'react-redux' +import store from 'store/store' +<% } %> + + export const unstable_settings = { - // Ensure that reloading on `/modal` keeps a back button present. - initialRouteName: "(tabs)", +// Ensure that reloading on `/modal` keeps a back button present. +initialRouteName: "(tabs)", }; export default function RootLayout() { - <% if (props.stylingPackage?.name === "tamagui") { %> - const [loaded] = useFonts({ - Inter: require("@tamagui/font-inter/otf/Inter-Medium.otf"), - InterBold: require("@tamagui/font-inter/otf/Inter-Bold.otf") - }); +<% if (props.stylingPackage?.name === "tamagui") { %> +const [loaded] = useFonts({ +Inter: require("@tamagui/font-inter/otf/Inter-Medium.otf"), +InterBold: require("@tamagui/font-inter/otf/Inter-Bold.otf") +}); - useEffect(() => { - if (loaded) { - SplashScreen.hideAsync(); - } - }, [loaded]); +useEffect(() => { +if (loaded) { +SplashScreen.hideAsync(); +} +}, [loaded]); - if (!loaded) return null; - <% } %> +if (!loaded) return null; +<% } %> - return ( - <% if (props.stylingPackage?.name === "tamagui") { %> - - <% } else if (props.stylingPackage?.name === "restyle") { %> - - <% } %> - - - - - <% if (props.stylingPackage?.name === "tamagui") { %> - - <% } else if (props.stylingPackage?.name === "restyle") { %> - - <% } %> - ); +return ( +<% if (props.stylingPackage?.name === "tamagui") { %> + + <% } else if (props.stylingPackage?.name === "restyle") { %> + + <% } %> + <% if (props.stateManagementPackage?.name === "redux") { %> + + <% } %> + + + + + <% if (props.stateManagementPackage?.name === "redux") { %> + + <% } %> + <% if (props.stylingPackage?.name === "tamagui") { %> + +<% } else if (props.stylingPackage?.name === "restyle") { %> + +<% } %> +); } \ No newline at end of file diff --git a/cli/src/templates/packages/react-navigation/App.tsx.ejs b/cli/src/templates/packages/react-navigation/App.tsx.ejs index 88baafae..69556cf3 100644 --- a/cli/src/templates/packages/react-navigation/App.tsx.ejs +++ b/cli/src/templates/packages/react-navigation/App.tsx.ejs @@ -1,69 +1,95 @@ <% if (props.stylingPackage?.name === "nativewind") { %> - import './global.css'; +import './global.css'; <% } else if (props.stylingPackage?.name === "nativewinui") { %> - import './global.css'; - import 'expo-dev-client'; +import './global.css'; +import 'expo-dev-client'; <% } %> <% if (props.stylingPackage?.name === "unistyles") { %> import './unistyles'; <% } %> <% if (props.internalizationPackage?.name === "i18next") { %> - import './translation'; +import './translation'; <% } %> import "react-native-gesture-handler"; <% if (props.stylingPackage?.name === "tamagui") { %> - import React, { useEffect } from "react"; - import { TamaguiProvider } from 'tamagui'; - import * as SplashScreen from 'expo-splash-screen'; - import { useFonts } from 'expo-font'; +import React, { useEffect } from "react"; +import { TamaguiProvider } from 'tamagui'; +import * as SplashScreen from 'expo-splash-screen'; +import { useFonts } from 'expo-font'; - import config from './tamagui.config' +import config from './tamagui.config' - SplashScreen.preventAutoHideAsync(); +SplashScreen.preventAutoHideAsync(); <% } else if (props.stylingPackage?.name === "restyle") { %> - import { ThemeProvider } from '@shopify/restyle'; - import { theme } from 'theme'; +import { ThemeProvider } from '@shopify/restyle'; +import { theme } from 'theme'; <% } %> <% if (props.analyticsPackage?.name === "vexo-analytics") { %> - import { vexo } from 'vexo-analytics'; +import { vexo } from 'vexo-analytics'; - vexo(process.env.VEXO_API_KEY); // eslint-disable-line +vexo(process.env.VEXO_API_KEY); // eslint-disable-line - import RootStack from "./navigation"; // eslint-disable-line +import RootStack from "./navigation"; // eslint-disable-line <% } else { %> - import RootStack from "./navigation"; +import RootStack from "./navigation"; +<% } %> +<% if (props.stateManagementPackage?.name === "redux") { %> +import { Provider } from 'react-redux' +import store from 'store/store' <% } %> export default function App() { - <% if (props.stylingPackage?.name === "tamagui") { %> - const [loaded] = useFonts({ - Inter: require("@tamagui/font-inter/otf/Inter-Medium.otf"), - InterBold: require("@tamagui/font-inter/otf/Inter-Bold.otf"), - }); - - useEffect(() => { - if (loaded) { - SplashScreen.hideAsync(); - } - }, [loaded]) +<% if (props.stylingPackage?.name === "tamagui") { %> +const [loaded] = useFonts({ +Inter: require("@tamagui/font-inter/otf/Inter-Medium.otf"), +InterBold: require("@tamagui/font-inter/otf/Inter-Bold.otf"), +}); - if (!loaded) { - return null; - } +useEffect(() => { +if (loaded) { +SplashScreen.hideAsync(); +} +}, [loaded]) - return ( - - - - ); - <% } else if (props.stylingPackage?.name === "restyle") { %> - return ( - - - - ); - <% } else { %> - return ; - <% } %> +if (!loaded) { +return null; } + +return ( + + <% if (props.stateManagementPackage?.name === "redux") { %> + + <% } %> + + <% if (props.stateManagementPackage?.name === "redux") { %> + + <% } %> + +); +<% } else if (props.stylingPackage?.name === "restyle") { %> +return ( + + <% if (props.stateManagementPackage?.name === "redux") { %> + + <% } %> + + <% if (props.stateManagementPackage?.name === "redux") { %> + + + <% } %> + +); +<% } else { %> +return( +<% if (props.stateManagementPackage?.name === "redux") { %> + + <% } %> + + <% if (props.stateManagementPackage?.name === "redux") { %> + + +<% } %> +) +<% } %> +} \ No newline at end of file diff --git a/cli/src/templates/packages/redux/store/reducers/demoSlice.ts.ejs b/cli/src/templates/packages/redux/store/reducers/demoSlice.ts.ejs new file mode 100644 index 00000000..5507df0c --- /dev/null +++ b/cli/src/templates/packages/redux/store/reducers/demoSlice.ts.ejs @@ -0,0 +1,23 @@ +import { createSlice } from '@reduxjs/toolkit'; + +interface InitialState { +demo: undefined; +} + +const initialState: InitialState = { +demo: undefined, +}; + +export const demoSlice = createSlice({ +name: 'demo', +initialState, +reducers: { +setDemo: (state, action) => { +state.demo = action.payload; +}, +}, +}); + +export const { setDemo } = demoSlice.actions; + +export default demoSlice.reducer; \ No newline at end of file diff --git a/cli/src/templates/packages/redux/store/store.ts.ejs b/cli/src/templates/packages/redux/store/store.ts.ejs new file mode 100644 index 00000000..8a2f9c01 --- /dev/null +++ b/cli/src/templates/packages/redux/store/store.ts.ejs @@ -0,0 +1,23 @@ +import { combineReducers, configureStore } from '@reduxjs/toolkit' +import { useDispatch, useSelector } from 'react-redux' + +import demoReducer from './reducers/demoSlice' + + +const rootReducer = combineReducers({ +demo: demoReducer, +}) + + +const store = configureStore({ +reducer: rootReducer, +}) + +export default store + +export type RootState = ReturnType + + type AppDispatch = typeof store.dispatch + + export const useAppDispatch = useDispatch.withTypes() + export const useAppSelector = useSelector.withTypes() \ No newline at end of file diff --git a/cli/src/types.ts b/cli/src/types.ts index 48931900..ae30831d 100644 --- a/cli/src/types.ts +++ b/cli/src/types.ts @@ -26,7 +26,8 @@ export const availablePackages = [ 'restyle', 'unistyles', 'i18next', - 'vexo-analytics' + 'vexo-analytics', + 'redux' ] as const; export type AuthenticationSelect = 'supabase' | 'firebase' | undefined; @@ -43,6 +44,8 @@ export type Internalization = 'i18next'; export type Analytics = 'vexo-analytics'; +export type StateManagement = 'redux' | undefined; + export type SelectedComponents = | 'action-sheet' | 'activity-indicator' @@ -59,7 +62,7 @@ export type SelectedComponents = export type AvailablePackages = { name: (typeof availablePackages)[number]; - type: 'navigation' | 'styling' | 'authentication' | 'internationalization' | 'analytics'; + type: 'navigation' | 'styling' | 'authentication' | 'internationalization' | 'analytics' | 'state-management'; options?: { selectedComponents?: SelectedComponents[]; type?: NavigationTypes }; }; diff --git a/cli/src/utilities/configureProjectFiles.ts b/cli/src/utilities/configureProjectFiles.ts index 9f130d99..fe9ccace 100644 --- a/cli/src/utilities/configureProjectFiles.ts +++ b/cli/src/utilities/configureProjectFiles.ts @@ -21,7 +21,8 @@ export function configureProjectFiles( analyticsPackage: AvailablePackages | undefined, toolbox: Toolbox, cliResults: CliResults, - internalizationPackage: AvailablePackages | undefined + internalizationPackage: AvailablePackages | undefined, + stateManagementPackage: AvailablePackages | undefined ): string[] { // Define the files common to all templates to be generated let baseFiles = [ @@ -347,6 +348,13 @@ export function configureProjectFiles( files = [...files, ...i18nextFiles]; } + + // add redux files if needed + if (stateManagementPackage?.name === 'redux') { + const reduxFiles = ['packages/redux/store/store.ts.ejs', 'packages/redux/store/reducers/demoSlice.ts.ejs']; + + files = [...files, ...reduxFiles]; + } } // Add npmrc file if user is using pnpm diff --git a/cli/src/utilities/generateProjectFiles.ts b/cli/src/utilities/generateProjectFiles.ts index 15dd1ad5..db504b40 100644 --- a/cli/src/utilities/generateProjectFiles.ts +++ b/cli/src/utilities/generateProjectFiles.ts @@ -11,7 +11,8 @@ export function generateProjectFiles( packageManager: PackageManager, stylingPackage: AvailablePackages | undefined, toolbox: Toolbox, - internalizationPackage: AvailablePackages | undefined + internalizationPackage: AvailablePackages | undefined, + stateManagementPackage: AvailablePackages | undefined ) { const { projectName, packages, flags } = cliResults; @@ -67,6 +68,10 @@ export function generateProjectFiles( target = target.replace('packages/vexo-analytics/', ''); } + if (stateManagementPackage?.name === 'redux') { + target = target.replace('packages/redux/', ''); + } + const gen = toolbox.template.generate({ template, target: `./${projectName}/` + target, @@ -79,7 +84,8 @@ export function generateProjectFiles( packageManager, packages, stylingPackage, - internalizationPackage + internalizationPackage, + stateManagementPackage } }); diff --git a/cli/src/utilities/runCLI.ts b/cli/src/utilities/runCLI.ts index 6a7c6553..6e47a08e 100644 --- a/cli/src/utilities/runCLI.ts +++ b/cli/src/utilities/runCLI.ts @@ -10,7 +10,8 @@ import { NavigationTypes, PackageManager, SelectedComponents, - StylingSelect + StylingSelect, + StateManagement } from '../types'; import { loadConfigs, saveConfig } from './configStorage'; import { getDefaultPackageManagerVersion } from './getPackageManager'; @@ -346,6 +347,24 @@ export async function runCLI(toolbox: Toolbox, projectName: string): Promise Date: Sun, 3 Nov 2024 10:07:24 +0000 Subject: [PATCH 2/4] fix: revert some indentation changes --- cli/src/templates/base/App.tsx.ejs | 143 +++++++++--------- .../expo-router/drawer/app/_layout.tsx.ejs | 104 ++++++------- .../expo-router/stack/app/_layout.tsx.ejs | 84 +++++----- .../expo-router/tabs/app/_layout.tsx.ejs | 100 ++++++------ .../packages/react-navigation/App.tsx.ejs | 130 ++++++++-------- .../redux/store/reducers/demoSlice.ts.ejs | 18 +-- .../packages/redux/store/store.ts.ejs | 10 +- cli/src/utilities/configAnalytics.ts | 2 + cli/src/utilities/configureProjectFiles.ts | 4 +- cli/src/utilities/runCLI.ts | 1 + 10 files changed, 300 insertions(+), 296 deletions(-) diff --git a/cli/src/templates/base/App.tsx.ejs b/cli/src/templates/base/App.tsx.ejs index 03036309..1192bb82 100644 --- a/cli/src/templates/base/App.tsx.ejs +++ b/cli/src/templates/base/App.tsx.ejs @@ -2,30 +2,30 @@ import { ScreenContent } from 'components/ScreenContent'; import { StatusBar } from 'expo-status-bar'; <% if (props.internalizationPackage?.name === "i18next") { %> -import './translation'; -import { InternalizationExample } from 'components/InternalizationExample'; + import './translation'; + import { InternalizationExample } from 'components/InternalizationExample'; <% } %> <% if (props.stylingPackage?.name === "nativewind") { %> -import './global.css'; + import './global.css'; <% } else if (props.stylingPackage?.name === "nativewinui") { %> -import './global.css'; -import 'expo-dev-client'; + import './global.css'; + import 'expo-dev-client'; <% } else if (props.stylingPackage?.name === "restyle") { %> -import { ThemeProvider } from '@shopify/restyle'; -import { theme } from 'theme'; + import { ThemeProvider } from '@shopify/restyle'; + import { theme } from 'theme'; <% } else if (props.stylingPackage?.name === "tamagui") { %> -<% if (!props.internalizationPackage) { %> -import { Text } from 'react-native'; -<% } %> -import { TamaguiProvider } from 'tamagui'; -import config from './tamagui.config'; + <% if (!props.internalizationPackage) { %> + import { Text } from 'react-native'; + <% } %> + import { TamaguiProvider } from 'tamagui'; + import config from './tamagui.config'; <% } %> <% if (props.analyticsPackage?.name === "vexo-analytics") { %> -import { vexo } from 'vexo-analytics'; + import { vexo } from 'vexo-analytics'; -vexo(process.env.EXPO_PUBLIC_VEXO_API_KEY); + vexo(process.env.EXPO_PUBLIC_VEXO_API_KEY); <% } %> <% if (props.stateManagementPackage?.name === "redux") { %> @@ -35,62 +35,63 @@ import store from 'store/store' <% if (props.stylingPackage?.name === "restyle") {%> -export default function App() { -return ( - - <% if (props.stateManagementPackage?.name === "redux") { %> - - <% } %> - - <% if (props.internalizationPackage?.name === "i18next") { %> - - <% } %> - - <% if (props.stateManagementPackage?.name === "redux") { %> - - <% } %> - - -); -} + export default function App() { + return ( + + <% if (props.stateManagementPackage?.name === "redux") { %> + + <% } %> + + <% if (props.internalizationPackage?.name === "i18next") { %> + + <% } %> + + <% if (props.stateManagementPackage?.name === "redux") { %> + + <% } %> + + + ); + } <% } else if (props.stylingPackage?.name === "tamagui") {%> -export default function App() { -return ( - - <% if (props.stateManagementPackage?.name === "redux") { %> - - <% } %> - - <% if (props.internalizationPackage?.name === "i18next") { %> - - <% } else { %> - Open up App.tsx to start working on your app! - <% } %> - - <% if (props.stateManagementPackage?.name === "redux") { %> - - <% } %> - - -); -} + export default function App() { + return ( + + <% if (props.stateManagementPackage?.name === "redux") { %> + + <% } %> + + <% if (props.internalizationPackage?.name === "i18next") { %> + + <% } else { %> + Open up App.tsx to start working on your app! + <% } %> + + <% if (props.stateManagementPackage?.name === "redux") { %> + + <% } %> + + + ); + } <% } else { %> -export default function App() { -return ( -<> - <% if (props.stateManagementPackage?.name === "redux") { %> - - <% } %> - - <% if (props.internalizationPackage?.name === "i18next") { %> - - <% } %> - - <% if (props.stateManagementPackage?.name === "redux") { %> - - <% } %> - - -); -} -<% } %> \ No newline at end of file + export default function App() { + return ( + <> + <% if (props.stateManagementPackage?.name === "redux") { %> + + <% } %> + + <% if (props.internalizationPackage?.name === "i18next") { %> + + <% } %> + + <% if (props.stateManagementPackage?.name === "redux") { %> + + <% } %> + + + ); + } +<% } %> + diff --git a/cli/src/templates/packages/expo-router/drawer/app/_layout.tsx.ejs b/cli/src/templates/packages/expo-router/drawer/app/_layout.tsx.ejs index fd4b7af9..a1f14e4f 100644 --- a/cli/src/templates/packages/expo-router/drawer/app/_layout.tsx.ejs +++ b/cli/src/templates/packages/expo-router/drawer/app/_layout.tsx.ejs @@ -1,15 +1,15 @@ <% if (props.stylingPackage?.name === "nativewind") { %> -import '../global.css'; + import '../global.css'; <% } else if (props.stylingPackage?.name === "nativewinui") { %> -import '../global.css'; -import 'expo-dev-client'; + import '../global.css'; + import 'expo-dev-client'; <% } %> <% if (props.stylingPackage?.name === "unistyles") { %> import '../unistyles'; <% } %> <% if (props.internalizationPackage?.name === "i18next") { %> -import '../translation'; + import '../translation'; <% } %> import 'react-native-gesture-handler'; @@ -17,24 +17,24 @@ import { GestureHandlerRootView } from 'react-native-gesture-handler'; import { Stack } from 'expo-router'; <% if (props.stylingPackage?.name==="tamagui" ) { %> -import React, { useEffect } from "react"; -import { TamaguiProvider } from 'tamagui' -import { SplashScreen } from "expo-router"; -import { useFonts } from "expo-font"; + import React, { useEffect } from "react"; + import { TamaguiProvider } from 'tamagui' + import { SplashScreen } from "expo-router"; + import { useFonts } from "expo-font"; -import config from '../tamagui.config'; + import config from '../tamagui.config'; -SplashScreen.preventAutoHideAsync(); + SplashScreen.preventAutoHideAsync(); <% } else if (props.stylingPackage?.name === "restyle") { %> -import { ThemeProvider } from '@shopify/restyle'; - -import { theme } from '../theme'; + import { ThemeProvider } from '@shopify/restyle'; + + import { theme } from '../theme'; <% } %> <% if (props.analyticsPackage?.name === "vexo-analytics") { %> -import { vexo } from 'vexo-analytics'; + import { vexo } from 'vexo-analytics'; -vexo(process.env.EXPO_PUBLIC_VEXO_API_KEY); + vexo(process.env.EXPO_PUBLIC_VEXO_API_KEY); <% } %> <% if (props.stateManagementPackage?.name === "redux") { %> import { Provider } from 'react-redux' @@ -43,48 +43,48 @@ import store from 'store/store' export const unstable_settings = { -// Ensure that reloading on `/modal` keeps a back button present. -initialRouteName: "(drawer)", + // Ensure that reloading on `/modal` keeps a back button present. + initialRouteName: "(drawer)", }; export default function RootLayout() { -<% if (props.stylingPackage?.name==="tamagui" ) { %> -const [loaded] = useFonts({ -Inter: require("@tamagui/font-inter/otf/Inter-Medium.otf"), -InterBold: require("@tamagui/font-inter/otf/Inter-Bold.otf") -}); + <% if (props.stylingPackage?.name==="tamagui" ) { %> + const [loaded] = useFonts({ + Inter: require("@tamagui/font-inter/otf/Inter-Medium.otf"), + InterBold: require("@tamagui/font-inter/otf/Inter-Bold.otf") + }); -useEffect(() => { -if (loaded) { -SplashScreen.hideAsync(); -} -}, [loaded]); + useEffect(() => { + if (loaded) { + SplashScreen.hideAsync(); + } + }, [loaded]); -if (!loaded) return null; -<% } %> + if (!loaded) return null; + <% } %> -return ( -<% if (props.stylingPackage?.name === "tamagui") { %> - - <% } else if (props.stylingPackage?.name === "restyle") { %> - - <% } %> - - <% if (props.stateManagementPackage?.name === "redux") { %> - - <% } %> - - - - - <% if (props.stateManagementPackage?.name === "redux") { %> - + return ( + <% if (props.stylingPackage?.name === "tamagui") { %> + + <% } else if (props.stylingPackage?.name === "restyle") { %> + + <% } %> + + <% if (props.stateManagementPackage?.name === "redux") { %> + + <% } %> + + + + + <% if (props.stateManagementPackage?.name === "redux") { %> + + <% } %> + + <% if (props.stylingPackage?.name === "tamagui") { %> + + <% } else if (props.stylingPackage?.name === "restyle") { %> + <% } %> - - <% if (props.stylingPackage?.name === "tamagui") { %> - -<% } else if (props.stylingPackage?.name === "restyle") { %> - -<% } %> -); + ); } \ No newline at end of file diff --git a/cli/src/templates/packages/expo-router/stack/app/_layout.tsx.ejs b/cli/src/templates/packages/expo-router/stack/app/_layout.tsx.ejs index b337d0c0..237c62a3 100644 --- a/cli/src/templates/packages/expo-router/stack/app/_layout.tsx.ejs +++ b/cli/src/templates/packages/expo-router/stack/app/_layout.tsx.ejs @@ -1,31 +1,31 @@ <% if (props.stylingPackage?.name === "nativewind") { %> -import '../global.css'; + import '../global.css'; <% } %> <% if (props.stylingPackage?.name === "unistyles") { %> import '../unistyles'; <% } %> <% if (props.internalizationPackage?.name === "i18next") { %> -import '../translation'; + import '../translation'; <% } %> <% if (props.stylingPackage?.name === "tamagui") { %> -import { useFonts } from 'expo-font'; -import { SplashScreen, Stack } from 'expo-router'; -import { useEffect } from 'react'; -import { TamaguiProvider } from 'tamagui'; + import { useFonts } from 'expo-font'; + import { SplashScreen, Stack } from 'expo-router'; + import { useEffect } from 'react'; + import { TamaguiProvider } from 'tamagui'; -import config from '../tamagui.config'; + import config from '../tamagui.config'; <% } else if (props.stylingPackage?.name === "restyle") { %> -import { ThemeProvider } from '@shopify/restyle'; -import { theme } from 'theme'; + import { ThemeProvider } from '@shopify/restyle'; + import { theme } from 'theme'; <% } %> -import { Stack } from "expo-router"; + import { Stack } from "expo-router"; <% if (props.analyticsPackage?.name === "vexo-analytics") { %> -import { vexo } from 'vexo-analytics'; + import { vexo } from 'vexo-analytics'; -vexo(process.env.EXPO_PUBLIC_VEXO_API_KEY); + vexo(process.env.EXPO_PUBLIC_VEXO_API_KEY); <% } %> <% if (props.stateManagementPackage?.name === "redux") { %> import { Provider } from 'react-redux' @@ -35,38 +35,38 @@ import store from 'store/store' export default function Layout() { -<% if (props.stylingPackage?.name === "tamagui") { %> -const [loaded] = useFonts({ -Inter: require("@tamagui/font-inter/otf/Inter-Medium.otf"), -InterBold: require("@tamagui/font-inter/otf/Inter-Bold.otf") -}); + <% if (props.stylingPackage?.name === "tamagui") { %> + const [loaded] = useFonts({ + Inter: require("@tamagui/font-inter/otf/Inter-Medium.otf"), + InterBold: require("@tamagui/font-inter/otf/Inter-Bold.otf") + }); -useEffect(() => { -if (loaded) { -SplashScreen.hideAsync(); -} -}, [loaded]); + useEffect(() => { + if (loaded) { + SplashScreen.hideAsync(); + } + }, [loaded]); -if (!loaded) return null; -<% } %> + if (!loaded) return null; + <% } %> -return ( -<% if (props.stylingPackage?.name === "tamagui") { %> - - <% } else if (props.stylingPackage?.name === "restyle") { %> - - <% } %> - <% if (props.stateManagementPackage?.name === "redux") { %> - + return ( + <% if (props.stylingPackage?.name === "tamagui") { %> + + <% } else if (props.stylingPackage?.name === "restyle") { %> + + <% } %> + <% if (props.stateManagementPackage?.name === "redux") { %> + <% } %> - + <% if (props.stateManagementPackage?.name === "redux") { %> - - <% } %> - <% if (props.stylingPackage?.name === "tamagui") { %> - -<% } else if (props.stylingPackage?.name === "restyle") { %> - -<% } %> -); -} \ No newline at end of file + + <% } %> + <% if (props.stylingPackage?.name === "tamagui") { %> + + <% } else if (props.stylingPackage?.name === "restyle") { %> + + <% } %> + ); +} diff --git a/cli/src/templates/packages/expo-router/tabs/app/_layout.tsx.ejs b/cli/src/templates/packages/expo-router/tabs/app/_layout.tsx.ejs index 8c209caa..ebd72000 100644 --- a/cli/src/templates/packages/expo-router/tabs/app/_layout.tsx.ejs +++ b/cli/src/templates/packages/expo-router/tabs/app/_layout.tsx.ejs @@ -1,37 +1,37 @@ <% if (props.stylingPackage?.name === "nativewind") { %> -import '../global.css'; + import '../global.css'; <% } else if (props.stylingPackage?.name === "nativewinui") { %> -import '../global.css'; -import 'expo-dev-client'; + import '../global.css'; + import 'expo-dev-client'; <% } %> <% if (props.stylingPackage?.name === "unistyles") { %> import '../unistyles'; <% } %> <% if (props.internalizationPackage?.name === "i18next") { %> -import '../translation'; + import '../translation'; <% } %> <% if (props.stylingPackage?.name === "tamagui") { %> -import React, { useEffect } from "react"; -import { TamaguiProvider } from 'tamagui' -import { SplashScreen, Stack } from "expo-router"; -import { useFonts } from "expo-font"; + import React, { useEffect } from "react"; + import { TamaguiProvider } from 'tamagui' + import { SplashScreen, Stack } from "expo-router"; + import { useFonts } from "expo-font"; -import config from '../tamagui.config' + import config from '../tamagui.config' -SplashScreen.preventAutoHideAsync(); + SplashScreen.preventAutoHideAsync(); <% } else if (props.stylingPackage?.name === "restyle") { %> -import { ThemeProvider } from '@shopify/restyle'; -import { Stack } from 'expo-router'; -import { theme } from 'theme'; + import { ThemeProvider } from '@shopify/restyle'; + import { Stack } from 'expo-router'; + import { theme } from 'theme'; <% } else { %> -import { Stack } from "expo-router"; + import { Stack } from "expo-router"; <% } %> <% if (props.analyticsPackage?.name === "vexo-analytics") { %> -import { vexo } from 'vexo-analytics'; + import { vexo } from 'vexo-analytics'; -vexo(process.env.EXPO_PUBLIC_VEXO_API_KEY); + vexo(process.env.EXPO_PUBLIC_VEXO_API_KEY); <% } %> <% if (props.stateManagementPackage?.name === "redux") { %> @@ -41,46 +41,46 @@ import store from 'store/store' export const unstable_settings = { -// Ensure that reloading on `/modal` keeps a back button present. -initialRouteName: "(tabs)", + // Ensure that reloading on `/modal` keeps a back button present. + initialRouteName: "(tabs)", }; export default function RootLayout() { -<% if (props.stylingPackage?.name === "tamagui") { %> -const [loaded] = useFonts({ -Inter: require("@tamagui/font-inter/otf/Inter-Medium.otf"), -InterBold: require("@tamagui/font-inter/otf/Inter-Bold.otf") -}); + <% if (props.stylingPackage?.name === "tamagui") { %> + const [loaded] = useFonts({ + Inter: require("@tamagui/font-inter/otf/Inter-Medium.otf"), + InterBold: require("@tamagui/font-inter/otf/Inter-Bold.otf") + }); -useEffect(() => { -if (loaded) { -SplashScreen.hideAsync(); -} -}, [loaded]); + useEffect(() => { + if (loaded) { + SplashScreen.hideAsync(); + } + }, [loaded]); -if (!loaded) return null; -<% } %> + if (!loaded) return null; + <% } %> -return ( -<% if (props.stylingPackage?.name === "tamagui") { %> - - <% } else if (props.stylingPackage?.name === "restyle") { %> - - <% } %> - <% if (props.stateManagementPackage?.name === "redux") { %> - + return ( + <% if (props.stylingPackage?.name === "tamagui") { %> + + <% } else if (props.stylingPackage?.name === "restyle") { %> + + <% } %> + <% if (props.stateManagementPackage?.name === "redux") { %> + <% } %> - - - - + + + + <% if (props.stateManagementPackage?.name === "redux") { %> - - <% } %> - <% if (props.stylingPackage?.name === "tamagui") { %> - -<% } else if (props.stylingPackage?.name === "restyle") { %> - -<% } %> -); + + <% } %> + <% if (props.stylingPackage?.name === "tamagui") { %> + + <% } else if (props.stylingPackage?.name === "restyle") { %> + + <% } %> + ); } \ No newline at end of file diff --git a/cli/src/templates/packages/react-navigation/App.tsx.ejs b/cli/src/templates/packages/react-navigation/App.tsx.ejs index 69556cf3..16121a8a 100644 --- a/cli/src/templates/packages/react-navigation/App.tsx.ejs +++ b/cli/src/templates/packages/react-navigation/App.tsx.ejs @@ -1,38 +1,38 @@ <% if (props.stylingPackage?.name === "nativewind") { %> -import './global.css'; + import './global.css'; <% } else if (props.stylingPackage?.name === "nativewinui") { %> -import './global.css'; -import 'expo-dev-client'; + import './global.css'; + import 'expo-dev-client'; <% } %> <% if (props.stylingPackage?.name === "unistyles") { %> import './unistyles'; <% } %> <% if (props.internalizationPackage?.name === "i18next") { %> -import './translation'; + import './translation'; <% } %> import "react-native-gesture-handler"; <% if (props.stylingPackage?.name === "tamagui") { %> -import React, { useEffect } from "react"; -import { TamaguiProvider } from 'tamagui'; -import * as SplashScreen from 'expo-splash-screen'; -import { useFonts } from 'expo-font'; + import React, { useEffect } from "react"; + import { TamaguiProvider } from 'tamagui'; + import * as SplashScreen from 'expo-splash-screen'; + import { useFonts } from 'expo-font'; -import config from './tamagui.config' + import config from './tamagui.config' -SplashScreen.preventAutoHideAsync(); + SplashScreen.preventAutoHideAsync(); <% } else if (props.stylingPackage?.name === "restyle") { %> -import { ThemeProvider } from '@shopify/restyle'; -import { theme } from 'theme'; + import { ThemeProvider } from '@shopify/restyle'; + import { theme } from 'theme'; <% } %> <% if (props.analyticsPackage?.name === "vexo-analytics") { %> -import { vexo } from 'vexo-analytics'; + import { vexo } from 'vexo-analytics'; -vexo(process.env.VEXO_API_KEY); // eslint-disable-line + vexo(process.env.VEXO_API_KEY); // eslint-disable-line -import RootStack from "./navigation"; // eslint-disable-line + import RootStack from "./navigation"; // eslint-disable-line <% } else { %> -import RootStack from "./navigation"; + import RootStack from "./navigation"; <% } %> <% if (props.stateManagementPackage?.name === "redux") { %> import { Provider } from 'react-redux' @@ -40,56 +40,54 @@ import store from 'store/store' <% } %> export default function App() { -<% if (props.stylingPackage?.name === "tamagui") { %> -const [loaded] = useFonts({ -Inter: require("@tamagui/font-inter/otf/Inter-Medium.otf"), -InterBold: require("@tamagui/font-inter/otf/Inter-Bold.otf"), -}); - -useEffect(() => { -if (loaded) { -SplashScreen.hideAsync(); -} -}, [loaded]) + <% if (props.stylingPackage?.name === "tamagui") { %> + const [loaded] = useFonts({ + Inter: require("@tamagui/font-inter/otf/Inter-Medium.otf"), + InterBold: require("@tamagui/font-inter/otf/Inter-Bold.otf"), + }); -if (!loaded) { -return null; -} + useEffect(() => { + if (loaded) { + SplashScreen.hideAsync(); + } + }, [loaded]) -return ( - - <% if (props.stateManagementPackage?.name === "redux") { %> - - <% } %> - - <% if (props.stateManagementPackage?.name === "redux") { %> - - <% } %> - -); -<% } else if (props.stylingPackage?.name === "restyle") { %> -return ( - - <% if (props.stateManagementPackage?.name === "redux") { %> - - <% } %> - - <% if (props.stateManagementPackage?.name === "redux") { %> - + if (!loaded) { + return null; + } - <% } %> - -); -<% } else { %> -return( -<% if (props.stateManagementPackage?.name === "redux") { %> - - <% } %> - - <% if (props.stateManagementPackage?.name === "redux") { %> - - -<% } %> -) -<% } %> -} \ No newline at end of file + return ( + + <% if (props.stateManagementPackage?.name === "redux") { %> + + <% } %> + + <% if (props.stateManagementPackage?.name === "redux") { %> + + <% } %> + + ); + <% } else if (props.stylingPackage?.name === "restyle") { %> + return ( + + <% if (props.stateManagementPackage?.name === "redux") { %> + + <% } %> + + <% if (props.stateManagementPackage?.name === "redux") { %> + + <% } %> + + ); + <% } else { %> + return ( + <% if (props.stateManagementPackage?.name === "redux") { %> + + <% } %> + + <% if (props.stateManagementPackage?.name === "redux") { %> + + <% } %> + ); + <% } %> +} diff --git a/cli/src/templates/packages/redux/store/reducers/demoSlice.ts.ejs b/cli/src/templates/packages/redux/store/reducers/demoSlice.ts.ejs index 5507df0c..488f2d74 100644 --- a/cli/src/templates/packages/redux/store/reducers/demoSlice.ts.ejs +++ b/cli/src/templates/packages/redux/store/reducers/demoSlice.ts.ejs @@ -1,21 +1,21 @@ import { createSlice } from '@reduxjs/toolkit'; interface InitialState { -demo: undefined; + demo: undefined; } const initialState: InitialState = { -demo: undefined, + demo: undefined, }; export const demoSlice = createSlice({ -name: 'demo', -initialState, -reducers: { -setDemo: (state, action) => { -state.demo = action.payload; -}, -}, + name: 'demo', + initialState, + reducers: { + setDemo: (state, action) => { + state.demo = action.payload; + }, + }, }); export const { setDemo } = demoSlice.actions; diff --git a/cli/src/templates/packages/redux/store/store.ts.ejs b/cli/src/templates/packages/redux/store/store.ts.ejs index 8a2f9c01..d6834078 100644 --- a/cli/src/templates/packages/redux/store/store.ts.ejs +++ b/cli/src/templates/packages/redux/store/store.ts.ejs @@ -5,19 +5,19 @@ import demoReducer from './reducers/demoSlice' const rootReducer = combineReducers({ -demo: demoReducer, + demo: demoReducer, }) const store = configureStore({ -reducer: rootReducer, + reducer: rootReducer, }) export default store export type RootState = ReturnType - type AppDispatch = typeof store.dispatch +type AppDispatch = typeof store.dispatch - export const useAppDispatch = useDispatch.withTypes() - export const useAppSelector = useSelector.withTypes() \ No newline at end of file +export const useAppDispatch = useDispatch.withTypes() +export const useAppSelector = useSelector.withTypes() \ No newline at end of file diff --git a/cli/src/utilities/configAnalytics.ts b/cli/src/utilities/configAnalytics.ts index 40dad50a..c1e029aa 100644 --- a/cli/src/utilities/configAnalytics.ts +++ b/cli/src/utilities/configAnalytics.ts @@ -9,6 +9,7 @@ import { NavigationTypes, PackageManager, SelectedComponents, + StateManagement, StylingSelect } from '../types'; @@ -54,6 +55,7 @@ export async function storeConfigAnalytics({ osArch: string; osRelease: string; analytics: Analytics; + stateManagement?: StateManagement; } & Partial) { if (process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test') { console.log('Skipping analytics in development or test environment'); diff --git a/cli/src/utilities/configureProjectFiles.ts b/cli/src/utilities/configureProjectFiles.ts index fe9ccace..8c4c0aae 100644 --- a/cli/src/utilities/configureProjectFiles.ts +++ b/cli/src/utilities/configureProjectFiles.ts @@ -8,6 +8,7 @@ import { Internalization, NavigationSelect, NavigationTypes, + StateManagement, StylingSelect } from '../types'; import { getPackageManager, getVersionForPackageManager } from './getPackageManager'; @@ -404,7 +405,8 @@ export function configureProjectFiles( osPlatform: os.platform(), osArch: os.arch(), osRelease: os.release(), - analytics: analyticsPackage?.name as Analytics + analytics: analyticsPackage?.name as Analytics, + stateManagement: stateManagementPackage?.name as StateManagement }); return files; diff --git a/cli/src/utilities/runCLI.ts b/cli/src/utilities/runCLI.ts index 6e47a08e..982fdbf6 100644 --- a/cli/src/utilities/runCLI.ts +++ b/cli/src/utilities/runCLI.ts @@ -359,6 +359,7 @@ export async function runCLI(toolbox: Toolbox, projectName: string): Promise Date: Sun, 3 Nov 2024 19:01:49 +0000 Subject: [PATCH 3/4] add to analytics --- cli/src/templates/base/App.tsx.ejs | 8 ++++---- .../packages/expo-router/tabs/app/_layout.tsx.ejs | 1 - cli/src/utilities/configAnalytics.ts | 6 ++++-- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/cli/src/templates/base/App.tsx.ejs b/cli/src/templates/base/App.tsx.ejs index 1192bb82..dd6e272f 100644 --- a/cli/src/templates/base/App.tsx.ejs +++ b/cli/src/templates/base/App.tsx.ejs @@ -1,5 +1,9 @@ import { ScreenContent } from 'components/ScreenContent'; import { StatusBar } from 'expo-status-bar'; +<% if (props.stateManagementPackage?.name === "redux") { %> +import { Provider } from 'react-redux' +import store from 'store/store' +<% } %> <% if (props.internalizationPackage?.name === "i18next") { %> import './translation'; @@ -28,10 +32,6 @@ import { StatusBar } from 'expo-status-bar'; vexo(process.env.EXPO_PUBLIC_VEXO_API_KEY); <% } %> -<% if (props.stateManagementPackage?.name === "redux") { %> -import { Provider } from 'react-redux' -import store from 'store/store' -<% } %> <% if (props.stylingPackage?.name === "restyle") {%> diff --git a/cli/src/templates/packages/expo-router/tabs/app/_layout.tsx.ejs b/cli/src/templates/packages/expo-router/tabs/app/_layout.tsx.ejs index ebd72000..434aa0ec 100644 --- a/cli/src/templates/packages/expo-router/tabs/app/_layout.tsx.ejs +++ b/cli/src/templates/packages/expo-router/tabs/app/_layout.tsx.ejs @@ -33,7 +33,6 @@ import '../unistyles'; vexo(process.env.EXPO_PUBLIC_VEXO_API_KEY); <% } %> - <% if (props.stateManagementPackage?.name === "redux") { %> import { Provider } from 'react-redux' import store from 'store/store' diff --git a/cli/src/utilities/configAnalytics.ts b/cli/src/utilities/configAnalytics.ts index c1e029aa..f66eb258 100644 --- a/cli/src/utilities/configAnalytics.ts +++ b/cli/src/utilities/configAnalytics.ts @@ -38,7 +38,8 @@ export async function storeConfigAnalytics({ osPlatform, osArch, osRelease, - analytics + analytics, + stateManagement }: { timestamp: string; cesVersion: string; @@ -96,7 +97,8 @@ export async function storeConfigAnalytics({ osPlatform ?? '', osArch ?? '', osRelease ?? '', - analytics ?? '' + analytics ?? '', + stateManagement ?? '' ] ] }, From d8605df47253be1274db6a00464ddf1a81db9472 Mon Sep 17 00:00:00 2001 From: Daniel Williams Date: Sun, 3 Nov 2024 20:21:31 +0000 Subject: [PATCH 4/4] add redux support for nativewindui --- cli/src/commands/create-expo-stack.ts | 7 +++++++ .../packages/nativewindui/drawer/app/_layout.tsx.ejs | 11 +++++++++++ .../packages/nativewindui/stack/app/_layout.tsx.ejs | 10 ++++++++++ .../packages/nativewindui/tabs/app/_layout.tsx.ejs | 10 ++++++++++ cli/src/utilities/configureProjectFiles.ts | 10 +++++----- 5 files changed, 43 insertions(+), 5 deletions(-) diff --git a/cli/src/commands/create-expo-stack.ts b/cli/src/commands/create-expo-stack.ts index 0cf59787..fca71ab0 100644 --- a/cli/src/commands/create-expo-stack.ts +++ b/cli/src/commands/create-expo-stack.ts @@ -362,6 +362,13 @@ const command: GluegunCommand = { script += '--drawer+tabs '; } } + + const stateManagementPackage = cliResults.packages.find((p) => p.type === 'state-management'); + + if (stateManagementPackage) { + // currently only redux is supported + script += `--${stateManagementPackage.name} `; + } } else { // Add the packages cliResults.packages.forEach((p) => { diff --git a/cli/src/templates/packages/nativewindui/drawer/app/_layout.tsx.ejs b/cli/src/templates/packages/nativewindui/drawer/app/_layout.tsx.ejs index 2972a438..81c11ae8 100644 --- a/cli/src/templates/packages/nativewindui/drawer/app/_layout.tsx.ejs +++ b/cli/src/templates/packages/nativewindui/drawer/app/_layout.tsx.ejs @@ -1,6 +1,10 @@ import '../global.css'; import 'expo-dev-client'; import { ThemeProvider as NavThemeProvider } from '@react-navigation/native'; +<% if (props.stateManagementPackage?.name === "redux") { %> +import { Provider } from 'react-redux' +import store from 'store/store' +<% } %> <% if (props.stylingPackage?.options.selectedComponents.includes('action-sheet')) { %> import { ActionSheetProvider } from '@expo/react-native-action-sheet'; <% } %> @@ -34,6 +38,10 @@ export default function RootLayout() { /> {/* WRAP YOUR APP WITH ANY ADDITIONAL PROVIDERS HERE */} {/* */} + + <% if (props.stateManagementPackage?.name === "redux") { %> + + <% } %> <% if (props.stylingPackage?.options.selectedComponents.includes('bottom-sheet')) { %> @@ -54,6 +62,9 @@ export default function RootLayout() { <% } %> + <% if (props.stateManagementPackage?.name === "redux") { %> + + <% } %> {/* */} ); diff --git a/cli/src/templates/packages/nativewindui/stack/app/_layout.tsx.ejs b/cli/src/templates/packages/nativewindui/stack/app/_layout.tsx.ejs index 39d51068..59455142 100644 --- a/cli/src/templates/packages/nativewindui/stack/app/_layout.tsx.ejs +++ b/cli/src/templates/packages/nativewindui/stack/app/_layout.tsx.ejs @@ -2,6 +2,10 @@ import '../global.css'; import 'expo-dev-client'; import { ThemeProvider as NavThemeProvider } from '@react-navigation/native'; import { Icon } from '@roninoss/icons'; +<% if (props.stateManagementPackage?.name === "redux") { %> +import { Provider } from 'react-redux' +import store from 'store/store' +<% } %> <% if (props.stylingPackage?.options.selectedComponents.includes('action-sheet')) { %> import { ActionSheetProvider } from '@expo/react-native-action-sheet'; <% } %> @@ -37,6 +41,9 @@ export default function RootLayout() { /> {/* WRAP YOUR APP WITH ANY ADDITIONAL PROVIDERS HERE */} {/* */} + <% if (props.stateManagementPackage?.name === "redux") { %> + + <% } %> <% if (props.stylingPackage?.options.selectedComponents.includes('bottom-sheet')) { %> @@ -57,6 +64,9 @@ export default function RootLayout() { <% } %> + <% if (props.stateManagementPackage?.name === "redux") { %> + + <% } %> {/* */} ); diff --git a/cli/src/templates/packages/nativewindui/tabs/app/_layout.tsx.ejs b/cli/src/templates/packages/nativewindui/tabs/app/_layout.tsx.ejs index 9d8ef337..17a8077c 100644 --- a/cli/src/templates/packages/nativewindui/tabs/app/_layout.tsx.ejs +++ b/cli/src/templates/packages/nativewindui/tabs/app/_layout.tsx.ejs @@ -2,6 +2,10 @@ import '../global.css'; import 'expo-dev-client'; import { ThemeProvider as NavThemeProvider } from '@react-navigation/native'; import { Icon } from '@roninoss/icons'; +<% if (props.stateManagementPackage?.name === "redux") { %> +import { Provider } from 'react-redux' +import store from 'store/store' +<% } %> <% if (props.stylingPackage?.options.selectedComponents.includes('action-sheet')) { %> import { ActionSheetProvider } from '@expo/react-native-action-sheet'; <% } %> @@ -37,6 +41,9 @@ export default function RootLayout() { /> {/* WRAP YOUR APP WITH ANY ADDITIONAL PROVIDERS HERE */} {/* */} + <% if (props.stateManagementPackage?.name === "redux") { %> + + <% } %> <% if (props.stylingPackage?.options.selectedComponents.includes('bottom-sheet')) { %> @@ -56,6 +63,9 @@ export default function RootLayout() { <% if (props.stylingPackage?.options.selectedComponents.includes('bottom-sheet')) { %> + <% } %> + <% if (props.stateManagementPackage?.name === "redux") { %> + <% } %> {/* */} diff --git a/cli/src/utilities/configureProjectFiles.ts b/cli/src/utilities/configureProjectFiles.ts index 8c4c0aae..fc706ea8 100644 --- a/cli/src/utilities/configureProjectFiles.ts +++ b/cli/src/utilities/configureProjectFiles.ts @@ -349,13 +349,13 @@ export function configureProjectFiles( files = [...files, ...i18nextFiles]; } + } - // add redux files if needed - if (stateManagementPackage?.name === 'redux') { - const reduxFiles = ['packages/redux/store/store.ts.ejs', 'packages/redux/store/reducers/demoSlice.ts.ejs']; + // add redux files if needed + if (stateManagementPackage?.name === 'redux') { + const reduxFiles = ['packages/redux/store/store.ts.ejs', 'packages/redux/store/reducers/demoSlice.ts.ejs']; - files = [...files, ...reduxFiles]; - } + files = [...files, ...reduxFiles]; } // Add npmrc file if user is using pnpm