@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.
- package/README.md +435 -0
- package/bin/create-expo-stack.js +2 -0
- package/build/cli.js +49 -0
- package/build/commands/create-expo-stack.js +471 -0
- package/build/constants.js +39 -0
- package/build/templates/base/.gitignore.ejs +26 -0
- package/build/templates/base/.npmrc.ejs +1 -0
- package/build/templates/base/App.tsx.ejs +66 -0
- package/build/templates/base/app.json.ejs +69 -0
- package/build/templates/base/assets/adaptive-icon.png +0 -0
- package/build/templates/base/assets/favicon.png +0 -0
- package/build/templates/base/assets/icon.png +0 -0
- package/build/templates/base/assets/splash.png +0 -0
- package/build/templates/base/babel.config.js.ejs +38 -0
- package/build/templates/base/components/BackButton.tsx.ejs +23 -0
- package/build/templates/base/components/Button.tsx.ejs +42 -0
- package/build/templates/base/components/Container.tsx.ejs +14 -0
- package/build/templates/base/components/EditScreenInfo.tsx.ejs +44 -0
- package/build/templates/base/components/HeaderButton.tsx.ejs +31 -0
- package/build/templates/base/components/ScreenContent.tsx.ejs +40 -0
- package/build/templates/base/components/TabBarIcon.tsx.ejs +15 -0
- package/build/templates/base/eslint.config.js.ejs +15 -0
- package/build/templates/base/package.json.ejs +191 -0
- package/build/templates/base/prettier.config.js.ejs +11 -0
- package/build/templates/base/tsconfig.json.ejs +39 -0
- package/build/templates/packages/expo-router/drawer/app/(drawer)/(tabs)/_layout.tsx.ejs +40 -0
- package/build/templates/packages/expo-router/drawer/app/(drawer)/(tabs)/index.tsx.ejs +15 -0
- package/build/templates/packages/expo-router/drawer/app/(drawer)/(tabs)/two.tsx.ejs +15 -0
- package/build/templates/packages/expo-router/drawer/app/(drawer)/_layout.tsx.ejs +65 -0
- package/build/templates/packages/expo-router/drawer/app/(drawer)/index.tsx.ejs +15 -0
- package/build/templates/packages/expo-router/drawer/app/+html.tsx.ejs +49 -0
- package/build/templates/packages/expo-router/drawer/app/+not-found.tsx.ejs +100 -0
- package/build/templates/packages/expo-router/drawer/app/_layout.tsx.ejs +91 -0
- package/build/templates/packages/expo-router/drawer/app/modal.tsx.ejs +21 -0
- package/build/templates/packages/expo-router/expo-env.d.ts +4 -0
- package/build/templates/packages/expo-router/index.js.ejs +4 -0
- package/build/templates/packages/expo-router/metro.config.js.ejs +24 -0
- package/build/templates/packages/expo-router/stack/app/+html.tsx.ejs +49 -0
- package/build/templates/packages/expo-router/stack/app/+not-found.tsx.ejs +113 -0
- package/build/templates/packages/expo-router/stack/app/_layout.tsx.ejs +63 -0
- package/build/templates/packages/expo-router/stack/app/details.tsx.ejs +56 -0
- package/build/templates/packages/expo-router/stack/app/index.tsx.ejs +73 -0
- package/build/templates/packages/expo-router/tabs/app/(tabs)/_layout.tsx.ejs +52 -0
- package/build/templates/packages/expo-router/tabs/app/(tabs)/index.tsx.ejs +37 -0
- package/build/templates/packages/expo-router/tabs/app/(tabs)/two.tsx.ejs +37 -0
- package/build/templates/packages/expo-router/tabs/app/+html.tsx.ejs +49 -0
- package/build/templates/packages/expo-router/tabs/app/+not-found.tsx.ejs +110 -0
- package/build/templates/packages/expo-router/tabs/app/_layout.tsx.ejs +84 -0
- package/build/templates/packages/expo-router/tabs/app/modal.tsx.ejs +21 -0
- package/build/templates/packages/firebase/.env.ejs +8 -0
- package/build/templates/packages/firebase/metro.config.js.ejs +14 -0
- package/build/templates/packages/firebase/utils/firebase.ts.ejs +26 -0
- package/build/templates/packages/i18next/components/InternalizationExample.tsx.ejs +23 -0
- package/build/templates/packages/i18next/core/i18n/fallbackChecker.ts.ejs +13 -0
- package/build/templates/packages/i18next/core/i18n/init.ts.ejs +24 -0
- package/build/templates/packages/i18next/core/i18n/languageDetector.ts.ejs +13 -0
- package/build/templates/packages/i18next/translation/en.json.ejs +8 -0
- package/build/templates/packages/i18next/translation/fr.json.ejs +8 -0
- package/build/templates/packages/i18next/translation/index.ts.ejs +20 -0
- package/build/templates/packages/nativewind/components/BackButton.tsx.ejs +22 -0
- package/build/templates/packages/nativewind/components/Button.tsx.ejs +21 -0
- package/build/templates/packages/nativewind/components/Container.tsx.ejs +13 -0
- package/build/templates/packages/nativewind/components/EditScreenInfo.tsx.ejs +40 -0
- package/build/templates/packages/nativewind/components/ScreenContent.tsx.ejs +27 -0
- package/build/templates/packages/nativewind/global.css +3 -0
- package/build/templates/packages/nativewind/metro.config.js +7 -0
- package/build/templates/packages/nativewind/nativewind-env.d.ts +2 -0
- package/build/templates/packages/nativewind/tailwind.config.js.ejs +15 -0
- package/build/templates/packages/nativewindui/components/Container.tsx.ejs +14 -0
- package/build/templates/packages/nativewindui/components/EditScreenInfo.tsx.ejs +45 -0
- package/build/templates/packages/nativewindui/components/HeaderButton.tsx.ejs +31 -0
- package/build/templates/packages/nativewindui/components/ScreenContent.tsx.ejs +40 -0
- package/build/templates/packages/nativewindui/components/TabBarIcon.tsx.ejs +15 -0
- package/build/templates/packages/nativewindui/components/nativewindui/Icon/Icon.ios.tsx.ejs +52 -0
- package/build/templates/packages/nativewindui/components/nativewindui/Icon/Icon.tsx.ejs +58 -0
- package/build/templates/packages/nativewindui/components/nativewindui/Icon/index.ts.ejs +16 -0
- package/build/templates/packages/nativewindui/components/nativewindui/Icon/types.ts.ejs +18 -0
- package/build/templates/packages/nativewindui/components/nativewindui/ThemeToggle.tsx.ejs +33 -0
- package/build/templates/packages/nativewindui/drawer/app/(drawer)/(tabs)/_layout.tsx.ejs +28 -0
- package/build/templates/packages/nativewindui/drawer/app/(drawer)/(tabs)/index.tsx.ejs +15 -0
- package/build/templates/packages/nativewindui/drawer/app/(drawer)/(tabs)/two.tsx.ejs +15 -0
- package/build/templates/packages/nativewindui/drawer/app/(drawer)/_layout.tsx.ejs +35 -0
- package/build/templates/packages/nativewindui/drawer/app/(drawer)/index.tsx.ejs +535 -0
- package/build/templates/packages/nativewindui/drawer/app/+html.tsx.ejs +46 -0
- package/build/templates/packages/nativewindui/drawer/app/+not-found.tsx.ejs +83 -0
- package/build/templates/packages/nativewindui/drawer/app/_layout.tsx.ejs +75 -0
- package/build/templates/packages/nativewindui/drawer/app/modal.tsx.ejs +33 -0
- package/build/templates/packages/nativewindui/global.css.ejs +91 -0
- package/build/templates/packages/nativewindui/lib/cn.ts.ejs +6 -0
- package/build/templates/packages/nativewindui/lib/useColorScheme.tsx.ejs +21 -0
- package/build/templates/packages/nativewindui/nativewind-env.d.ts.ejs +1 -0
- package/build/templates/packages/nativewindui/stack/app/+html.tsx.ejs +46 -0
- package/build/templates/packages/nativewindui/stack/app/+not-found.tsx.ejs +18 -0
- package/build/templates/packages/nativewindui/stack/app/_layout.tsx.ejs +78 -0
- package/build/templates/packages/nativewindui/stack/app/index.tsx.ejs +487 -0
- package/build/templates/packages/nativewindui/stack/app/modal.tsx.ejs +33 -0
- package/build/templates/packages/nativewindui/tabs/app/(tabs)/_layout.tsx.ejs +35 -0
- package/build/templates/packages/nativewindui/tabs/app/(tabs)/index.tsx.ejs +537 -0
- package/build/templates/packages/nativewindui/tabs/app/(tabs)/two.tsx.ejs +22 -0
- package/build/templates/packages/nativewindui/tabs/app/+html.tsx.ejs +46 -0
- package/build/templates/packages/nativewindui/tabs/app/+not-found.tsx.ejs +90 -0
- package/build/templates/packages/nativewindui/tabs/app/_layout.tsx.ejs +78 -0
- package/build/templates/packages/nativewindui/tabs/app/modal.tsx.ejs +21 -0
- package/build/templates/packages/nativewindui/tailwind.config.js.ejs +67 -0
- package/build/templates/packages/nativewindui/theme/colors.ts.ejs +123 -0
- package/build/templates/packages/nativewindui/theme/index.ts.ejs +32 -0
- package/build/templates/packages/nativewindui/theme/with-opacity.ts.ejs +155 -0
- package/build/templates/packages/react-navigation/App.tsx.ejs +73 -0
- package/build/templates/packages/react-navigation/navigation/drawer-navigator.tsx.ejs +31 -0
- package/build/templates/packages/react-navigation/navigation/index.tsx.ejs +108 -0
- package/build/templates/packages/react-navigation/navigation/tab-navigator.tsx.ejs +38 -0
- package/build/templates/packages/react-navigation/screens/details.tsx.ejs +41 -0
- package/build/templates/packages/react-navigation/screens/home.tsx.ejs +5 -0
- package/build/templates/packages/react-navigation/screens/modal.tsx.ejs +20 -0
- package/build/templates/packages/react-navigation/screens/one.tsx.ejs +5 -0
- package/build/templates/packages/react-navigation/screens/overview.tsx.ejs +54 -0
- package/build/templates/packages/react-navigation/screens/two.tsx.ejs +5 -0
- package/build/templates/packages/restyle/components/BackButton.tsx.ejs +19 -0
- package/build/templates/packages/restyle/components/Button.tsx.ejs +32 -0
- package/build/templates/packages/restyle/components/Container.tsx.ejs +16 -0
- package/build/templates/packages/restyle/components/EditScreenInfo.tsx.ejs +38 -0
- package/build/templates/packages/restyle/components/ScreenContent.tsx.ejs +30 -0
- package/build/templates/packages/restyle/theme.ts.ejs +51 -0
- package/build/templates/packages/supabase/.env.ejs +2 -0
- package/build/templates/packages/supabase/utils/supabase.ts.ejs +14 -0
- package/build/templates/packages/tamagui/components/BackButton.tsx.ejs +12 -0
- package/build/templates/packages/tamagui/components/Button.tsx.ejs +17 -0
- package/build/templates/packages/tamagui/components/Container.tsx.ejs +12 -0
- package/build/templates/packages/tamagui/components/EditScreenInfo.tsx.ejs +27 -0
- package/build/templates/packages/tamagui/components/ScreenContent.tsx.ejs +23 -0
- package/build/templates/packages/tamagui/tamagui.config.ts.ejs +14 -0
- package/build/templates/packages/unistyles/breakpoints.ts.ejs +9 -0
- package/build/templates/packages/unistyles/components/BackButton.tsx.ejs +28 -0
- package/build/templates/packages/unistyles/components/Button.tsx.ejs +42 -0
- package/build/templates/packages/unistyles/components/Container.tsx.ejs +17 -0
- package/build/templates/packages/unistyles/components/EditScreenInfo.tsx.ejs +53 -0
- package/build/templates/packages/unistyles/components/ScreenContent.tsx.ejs +43 -0
- package/build/templates/packages/unistyles/theme.ts.ejs +34 -0
- package/build/templates/packages/unistyles/unistyles.ts.ejs +27 -0
- package/build/templates/packages/uniwind/global.css +2 -0
- package/build/templates/packages/uniwind/metro.config.js.ejs +10 -0
- package/build/templates/packages/vexo-analytics/.env.ejs +7 -0
- package/build/templates/packages/zustand/store/store.ts.ejs +15 -0
- package/build/types/cli.d.ts +4 -0
- package/build/types/commands/create-expo-stack.d.ts +3 -0
- package/build/types/constants.d.ts +10 -0
- package/build/types/types.d.ts +33 -0
- package/build/types/utilities/bumpVersion.d.ts +1 -0
- package/build/types/utilities/clearNavigationPackages.d.ts +2 -0
- package/build/types/utilities/clearStylingPackages.d.ts +2 -0
- package/build/types/utilities/configAnalytics.d.ts +18 -0
- package/build/types/utilities/configStorage.d.ts +8 -0
- package/build/types/utilities/configureProjectFiles.d.ts +3 -0
- package/build/types/utilities/copyBaseAssets.d.ts +2 -0
- package/build/types/utilities/generateNWUI.d.ts +3 -0
- package/build/types/utilities/generateProjectFiles.d.ts +5 -0
- package/build/types/utilities/getPackageManager.d.ts +8 -0
- package/build/types/utilities/index.d.ts +10 -0
- package/build/types/utilities/printOutput.d.ts +3 -0
- package/build/types/utilities/publishToGitHub.d.ts +2 -0
- package/build/types/utilities/renderTitle.d.ts +2 -0
- package/build/types/utilities/runCLI.d.ts +3 -0
- package/build/types/utilities/runEasConfigure.d.ts +3 -0
- package/build/types/utilities/runIgnite.d.ts +3 -0
- package/build/types/utilities/showHelp.d.ts +1 -0
- package/build/types/utilities/systemCommand.d.ts +14 -0
- package/build/types/utilities/usePackage.d.ts +2 -0
- package/build/types/utilities/validateProjectName.d.ts +4 -0
- package/build/types.js +39 -0
- package/build/utilities/bumpVersion.js +21 -0
- package/build/utilities/clearNavigationPackages.js +11 -0
- package/build/utilities/clearStylingPackages.js +11 -0
- package/build/utilities/configAnalytics.js +70 -0
- package/build/utilities/configStorage.js +50 -0
- package/build/utilities/configureProjectFiles.js +380 -0
- package/build/utilities/copyBaseAssets.js +21 -0
- package/build/utilities/generateNWUI.js +54 -0
- package/build/utilities/generateProjectFiles.js +106 -0
- package/build/utilities/getPackageManager.js +103 -0
- package/build/utilities/index.js +27 -0
- package/build/utilities/printOutput.js +251 -0
- package/build/utilities/publishToGitHub.js +173 -0
- package/build/utilities/renderTitle.js +55 -0
- package/build/utilities/runCLI.js +437 -0
- package/build/utilities/runEasConfigure.js +83 -0
- package/build/utilities/runIgnite.js +26 -0
- package/build/utilities/showHelp.js +85 -0
- package/build/utilities/systemCommand.js +40 -0
- package/build/utilities/usePackage.js +8 -0
- package/build/utilities/validateProjectName.js +42 -0
- package/package.json +77 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { forwardRef } from 'react';
|
|
2
|
+
import { Text, TouchableOpacity, TouchableOpacityProps, View } from 'react-native';
|
|
3
|
+
|
|
4
|
+
interface ButtonProps extends TouchableOpacityProps {
|
|
5
|
+
title: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export const Button = forwardRef<View, ButtonProps>(({ title, ...touchableProps }, ref) => {
|
|
9
|
+
return (
|
|
10
|
+
<TouchableOpacity ref={ref} {...touchableProps} className={`${styles.button} ${touchableProps.className}`}>
|
|
11
|
+
<Text className={styles.buttonText}>{title}</Text>
|
|
12
|
+
</TouchableOpacity>
|
|
13
|
+
);
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
Button.displayName = 'Button';
|
|
17
|
+
|
|
18
|
+
const styles = {
|
|
19
|
+
button: 'items-center bg-indigo-500 rounded-[28px] shadow-md p-4',
|
|
20
|
+
buttonText: 'text-white text-lg font-semibold text-center',
|
|
21
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { View } from 'react-native';
|
|
2
|
+
|
|
3
|
+
interface ContainerProps {
|
|
4
|
+
children: React.ReactNode;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export const Container: React.FC<ContainerProps> = ({ children }) => {
|
|
8
|
+
return <View className={styles.container}>{children}</View>;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
const styles = {
|
|
12
|
+
container: "flex flex-1 p-safe bg-white",
|
|
13
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Text, View } from 'react-native';
|
|
2
|
+
|
|
3
|
+
<% if (props.internalizationPackage?.name === "i18next") { %>
|
|
4
|
+
import { useTranslation } from 'react-i18next';
|
|
5
|
+
<% } %>
|
|
6
|
+
|
|
7
|
+
interface EditScreenInfoProps {
|
|
8
|
+
path: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const EditScreenInfo: React.FC<EditScreenInfoProps> = ({ path }) => {
|
|
12
|
+
<% if (props.internalizationPackage?.name === "i18next") { %>
|
|
13
|
+
const { t } = useTranslation();
|
|
14
|
+
const title = t('getStarted');
|
|
15
|
+
const description = t('changeCode')
|
|
16
|
+
<% } else { %>
|
|
17
|
+
const title = "Open up the code for this screen:"
|
|
18
|
+
const description = "Change any of the text, save the file, and your app will automatically update."
|
|
19
|
+
<% } %>
|
|
20
|
+
return (
|
|
21
|
+
<View>
|
|
22
|
+
<View className={styles.getStartedContainer}>
|
|
23
|
+
<Text className={styles.getStartedText}>{title}</Text>
|
|
24
|
+
<View className={`${styles.codeHighlightContainer} ${styles.homeScreenFilename}`}>
|
|
25
|
+
<Text>{path}</Text>
|
|
26
|
+
</View>
|
|
27
|
+
<Text className={styles.getStartedText}>
|
|
28
|
+
{description}
|
|
29
|
+
</Text>
|
|
30
|
+
</View>
|
|
31
|
+
</View>
|
|
32
|
+
);
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const styles = {
|
|
36
|
+
codeHighlightContainer: `rounded-md px-1`,
|
|
37
|
+
getStartedContainer: `items-center mx-12`,
|
|
38
|
+
getStartedText: `text-lg leading-6 text-center`,
|
|
39
|
+
homeScreenFilename: `my-2`,
|
|
40
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Text, View } from 'react-native';
|
|
3
|
+
|
|
4
|
+
import { EditScreenInfo } from './EditScreenInfo';
|
|
5
|
+
|
|
6
|
+
interface ScreenContentProps {
|
|
7
|
+
title: string;
|
|
8
|
+
path: string;
|
|
9
|
+
children?: React.ReactNode;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const ScreenContent: React.FC<ScreenContentProps> = ({ title, path, children }) => {
|
|
13
|
+
return (
|
|
14
|
+
<View className={styles.container}>
|
|
15
|
+
<Text className={styles.title}>{title}</Text>
|
|
16
|
+
<View className={styles.separator} />
|
|
17
|
+
<EditScreenInfo path={path} />
|
|
18
|
+
{children}
|
|
19
|
+
</View>
|
|
20
|
+
);
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const styles = {
|
|
24
|
+
container: `items-center flex-1 justify-center bg-white`,
|
|
25
|
+
separator: `h-[1px] my-7 w-4/5 bg-gray-200`,
|
|
26
|
+
title: `text-xl font-bold`,
|
|
27
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
const { getDefaultConfig } = require('expo/metro-config');
|
|
2
|
+
const { withNativeWind } = require('nativewind/metro');
|
|
3
|
+
|
|
4
|
+
// eslint-disable-next-line no-undef
|
|
5
|
+
const config = getDefaultConfig(__dirname);
|
|
6
|
+
|
|
7
|
+
module.exports = withNativeWind(config, { input: './global.css' });
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/** @type {import('tailwindcss').Config} */
|
|
2
|
+
module.exports = {
|
|
3
|
+
<% if (props.navigationPackage?.name === "react-navigation") { %>
|
|
4
|
+
content: ["./App.{js,ts,tsx}", "./components/**/*.{js,ts,tsx}", "./screens/**/*.{js,ts,tsx}", "./navigation/**/*.{js,ts,tsx}"],
|
|
5
|
+
<% } else if (props.navigationPackage?.name === "expo-router") { %>
|
|
6
|
+
content: ["./app/**/*.{js,ts,tsx}", "./components/**/*.{js,ts,tsx}"],
|
|
7
|
+
<% } else { %>
|
|
8
|
+
content: ["./App.{js,ts,tsx}", "./components/**/*.{js,ts,tsx}"],
|
|
9
|
+
<% } %>
|
|
10
|
+
presets: [require("nativewind/preset")],
|
|
11
|
+
theme: {
|
|
12
|
+
extend: {},
|
|
13
|
+
},
|
|
14
|
+
plugins: [],
|
|
15
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { StyleSheet, SafeAreaView } from 'react-native';
|
|
2
|
+
|
|
3
|
+
export const Container = ({ children }: { children: React.ReactNode }) => {
|
|
4
|
+
return <SafeAreaView style={styles.container}>{children}</SafeAreaView>;
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
const styles = StyleSheet.create({
|
|
8
|
+
container: {
|
|
9
|
+
flex: 1,
|
|
10
|
+
padding: 24,
|
|
11
|
+
backgroundColor: 'white',
|
|
12
|
+
},
|
|
13
|
+
});
|
|
14
|
+
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { StyleSheet, View } from 'react-native';
|
|
2
|
+
|
|
3
|
+
import { Text } from '@/components/nativewindui/Text';
|
|
4
|
+
|
|
5
|
+
<% if (props.internalizationPackage?.name === "i18next") { %>
|
|
6
|
+
import { useTranslation } from 'react-i18next';
|
|
7
|
+
<% } %>
|
|
8
|
+
|
|
9
|
+
export default function EditScreenInfo({ path }: { path: string }) {
|
|
10
|
+
<% if (props.internalizationPackage?.name === "i18next") { %>
|
|
11
|
+
const { t } = useTranslation();
|
|
12
|
+
const title = t('getStarted');
|
|
13
|
+
const description = t('changeCode')
|
|
14
|
+
<% } else { %>
|
|
15
|
+
const title = "Open up the code for this screen:"
|
|
16
|
+
const description = "Change any of the text, save the file, and your app will automatically update."
|
|
17
|
+
<% } %>
|
|
18
|
+
return (
|
|
19
|
+
<View style={styles.getStartedContainer}>
|
|
20
|
+
<Text variant="heading" className="text-center">
|
|
21
|
+
{title}
|
|
22
|
+
</Text>
|
|
23
|
+
<View style={[styles.codeHighlightContainer, styles.homeScreenFilename]}>
|
|
24
|
+
<Text>{path}</Text>
|
|
25
|
+
</View>
|
|
26
|
+
<Text variant="body" className="text-center">
|
|
27
|
+
{description}
|
|
28
|
+
</Text>
|
|
29
|
+
</View>
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const styles = StyleSheet.create({
|
|
34
|
+
codeHighlightContainer: {
|
|
35
|
+
borderRadius: 3,
|
|
36
|
+
paddingHorizontal: 4,
|
|
37
|
+
},
|
|
38
|
+
getStartedContainer: {
|
|
39
|
+
alignItems: 'center',
|
|
40
|
+
marginHorizontal: 50,
|
|
41
|
+
},
|
|
42
|
+
homeScreenFilename: {
|
|
43
|
+
marginVertical: 7,
|
|
44
|
+
},
|
|
45
|
+
});
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { forwardRef } from 'react';
|
|
2
|
+
import FontAwesome from '@expo/vector-icons/FontAwesome';
|
|
3
|
+
import { Pressable, StyleSheet } from 'react-native';
|
|
4
|
+
|
|
5
|
+
export const HeaderButton = forwardRef<typeof Pressable, { onPress?: () => void; }>(({ onPress }, ref) => {
|
|
6
|
+
return (
|
|
7
|
+
<Pressable onPress={onPress}>
|
|
8
|
+
{({ pressed }) => (
|
|
9
|
+
<FontAwesome
|
|
10
|
+
name="info-circle"
|
|
11
|
+
size={25}
|
|
12
|
+
color="gray"
|
|
13
|
+
style={[
|
|
14
|
+
styles.headerRight,
|
|
15
|
+
{
|
|
16
|
+
opacity: pressed ? 0.5 : 1,
|
|
17
|
+
},
|
|
18
|
+
]}
|
|
19
|
+
/>
|
|
20
|
+
)}
|
|
21
|
+
</Pressable>
|
|
22
|
+
);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
HeaderButton.displayName = 'HeaderButton';
|
|
26
|
+
|
|
27
|
+
export const styles = StyleSheet.create({
|
|
28
|
+
headerRight: {
|
|
29
|
+
marginRight: 15,
|
|
30
|
+
},
|
|
31
|
+
});
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { StyleSheet, View } from 'react-native';
|
|
3
|
+
|
|
4
|
+
import { Text } from '@/components/nativewindui/Text';
|
|
5
|
+
|
|
6
|
+
import EditScreenInfo from './EditScreenInfo';
|
|
7
|
+
|
|
8
|
+
type ScreenContentProps = {
|
|
9
|
+
title: string;
|
|
10
|
+
path: string;
|
|
11
|
+
children?: React.ReactNode;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export const ScreenContent = ({ title, path, children }: ScreenContentProps) => {
|
|
15
|
+
return (
|
|
16
|
+
<View style={styles.container}>
|
|
17
|
+
<Text variant="title1" className="text-center">
|
|
18
|
+
{title}
|
|
19
|
+
</Text>
|
|
20
|
+
<View style={styles.separator} />
|
|
21
|
+
<EditScreenInfo path={path} />
|
|
22
|
+
{children}
|
|
23
|
+
</View>
|
|
24
|
+
);
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const styles = StyleSheet.create({
|
|
28
|
+
container: {
|
|
29
|
+
alignItems: 'center',
|
|
30
|
+
backgroundColor: 'white',
|
|
31
|
+
flex: 1,
|
|
32
|
+
justifyContent: 'center',
|
|
33
|
+
},
|
|
34
|
+
separator: {
|
|
35
|
+
backgroundColor: '#d1d5db',
|
|
36
|
+
height: 1,
|
|
37
|
+
marginVertical: 30,
|
|
38
|
+
width: '80%',
|
|
39
|
+
},
|
|
40
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import FontAwesome from '@expo/vector-icons/FontAwesome';
|
|
2
|
+
import { StyleSheet } from 'react-native';
|
|
3
|
+
|
|
4
|
+
export const TabBarIcon = (props: {
|
|
5
|
+
name: React.ComponentProps<typeof FontAwesome>['name'];
|
|
6
|
+
color: string;
|
|
7
|
+
}) => {
|
|
8
|
+
return <FontAwesome size={28} style={styles.tabBarIcon} {...props} />;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export const styles = StyleSheet.create({
|
|
12
|
+
tabBarIcon: {
|
|
13
|
+
marginBottom: -3,
|
|
14
|
+
},
|
|
15
|
+
});
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { SymbolView } from 'expo-symbols';
|
|
2
|
+
|
|
3
|
+
import type { IconProps } from './types';
|
|
4
|
+
|
|
5
|
+
import { useColorScheme } from '@/lib/useColorScheme';
|
|
6
|
+
|
|
7
|
+
function Icon({
|
|
8
|
+
materialCommunityIcon: _materialCommunityIcon,
|
|
9
|
+
materialIcon: _materialIcon,
|
|
10
|
+
sfSymbol,
|
|
11
|
+
name,
|
|
12
|
+
color,
|
|
13
|
+
size = 24,
|
|
14
|
+
...props
|
|
15
|
+
}: IconProps) {
|
|
16
|
+
const { colors } = useColorScheme();
|
|
17
|
+
return (
|
|
18
|
+
<SymbolView
|
|
19
|
+
name={name ?? 'questionmark'}
|
|
20
|
+
tintColor={rgbaToHex(color ?? colors.foreground)}
|
|
21
|
+
size={size}
|
|
22
|
+
resizeMode="scaleAspectFit"
|
|
23
|
+
{...props}
|
|
24
|
+
{...sfSymbol}
|
|
25
|
+
/>
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export { Icon };
|
|
30
|
+
|
|
31
|
+
// TODO: seems like the need to convert rgba to hex color is a bug in expo-symbols, accordion to the docs, it should accept a hex color, but it doesn't.
|
|
32
|
+
|
|
33
|
+
function rgbaToHex(color: string): string {
|
|
34
|
+
if (!color) return 'black';
|
|
35
|
+
const rgbaRegex =
|
|
36
|
+
/^rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})(?:\s*,\s*(\d*\.?\d+))?\s*\)$/i;
|
|
37
|
+
const match = color.match(rgbaRegex);
|
|
38
|
+
|
|
39
|
+
if (!match) {
|
|
40
|
+
return color;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const [, rStr, gStr, bStr, aStr] = match;
|
|
44
|
+
const r = Math.min(255, parseInt(rStr));
|
|
45
|
+
const g = Math.min(255, parseInt(gStr));
|
|
46
|
+
const b = Math.min(255, parseInt(bStr));
|
|
47
|
+
const a = aStr !== undefined ? Math.round(parseFloat(aStr) * 255) : 255;
|
|
48
|
+
|
|
49
|
+
const toHex = (n: number) => n.toString(16).padStart(2, '0');
|
|
50
|
+
|
|
51
|
+
return `#${toHex(r)}${toHex(g)}${toHex(b)}${a < 255 ? toHex(a) : ''}`;
|
|
52
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import MaterialCommunityIcons from '@expo/vector-icons/MaterialCommunityIcons';
|
|
2
|
+
import MaterialIcons from '@expo/vector-icons/MaterialIcons';
|
|
3
|
+
import {
|
|
4
|
+
SF_SYMBOLS_TO_MATERIAL_COMMUNITY_ICONS,
|
|
5
|
+
SF_SYMBOLS_TO_MATERIAL_ICONS,
|
|
6
|
+
} from 'rn-icon-mapper';
|
|
7
|
+
|
|
8
|
+
import type { IconProps } from './types';
|
|
9
|
+
|
|
10
|
+
import { useColorScheme } from '@/lib/useColorScheme';
|
|
11
|
+
|
|
12
|
+
function Icon({
|
|
13
|
+
name,
|
|
14
|
+
materialCommunityIcon,
|
|
15
|
+
materialIcon,
|
|
16
|
+
sfSymbol: _sfSymbol,
|
|
17
|
+
size = 24,
|
|
18
|
+
...props
|
|
19
|
+
}: IconProps) {
|
|
20
|
+
const { colors } = useColorScheme();
|
|
21
|
+
const defaultColor = colors.foreground;
|
|
22
|
+
|
|
23
|
+
if (materialCommunityIcon) {
|
|
24
|
+
return (
|
|
25
|
+
<MaterialCommunityIcons
|
|
26
|
+
size={size}
|
|
27
|
+
color={defaultColor}
|
|
28
|
+
{...props}
|
|
29
|
+
{...materialCommunityIcon}
|
|
30
|
+
/>
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
if (materialIcon) {
|
|
34
|
+
return <MaterialIcons size={size} color={defaultColor} {...props} {...materialIcon} />;
|
|
35
|
+
}
|
|
36
|
+
const materialCommunityIconName =
|
|
37
|
+
SF_SYMBOLS_TO_MATERIAL_COMMUNITY_ICONS[
|
|
38
|
+
name as keyof typeof SF_SYMBOLS_TO_MATERIAL_COMMUNITY_ICONS
|
|
39
|
+
];
|
|
40
|
+
if (materialCommunityIconName) {
|
|
41
|
+
return (
|
|
42
|
+
<MaterialCommunityIcons
|
|
43
|
+
name={materialCommunityIconName}
|
|
44
|
+
size={size}
|
|
45
|
+
color={defaultColor}
|
|
46
|
+
{...props}
|
|
47
|
+
/>
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
const materialIconName =
|
|
51
|
+
SF_SYMBOLS_TO_MATERIAL_ICONS[name as keyof typeof SF_SYMBOLS_TO_MATERIAL_ICONS];
|
|
52
|
+
if (materialIconName) {
|
|
53
|
+
return <MaterialIcons name={materialIconName} size={size} color={defaultColor} {...props} />;
|
|
54
|
+
}
|
|
55
|
+
return <MaterialCommunityIcons name="help" size={size} color={defaultColor} {...props} />;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export { Icon };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { cssInterop } from 'nativewind';
|
|
2
|
+
|
|
3
|
+
import { Icon } from './Icon';
|
|
4
|
+
|
|
5
|
+
cssInterop(Icon, {
|
|
6
|
+
className: {
|
|
7
|
+
target: 'style',
|
|
8
|
+
nativeStyleToProp: {
|
|
9
|
+
color: 'color',
|
|
10
|
+
height: 'size',
|
|
11
|
+
width: 'size',
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
export { Icon };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type MaterialCommunityIcons from '@expo/vector-icons/MaterialCommunityIcons';
|
|
2
|
+
import type MaterialIcons from '@expo/vector-icons/MaterialIcons';
|
|
3
|
+
import type { SymbolViewProps } from 'expo-symbols';
|
|
4
|
+
import type { IconMapper } from 'rn-icon-mapper';
|
|
5
|
+
|
|
6
|
+
type MaterialCommunityIconsProps = React.ComponentProps<typeof MaterialCommunityIcons>;
|
|
7
|
+
type MaterialIconsProps = React.ComponentProps<typeof MaterialIcons>;
|
|
8
|
+
|
|
9
|
+
type Style = SymbolViewProps['style'] &
|
|
10
|
+
MaterialIconsProps['style'] &
|
|
11
|
+
MaterialCommunityIconsProps['style'];
|
|
12
|
+
|
|
13
|
+
type IconProps = IconMapper<SymbolViewProps, MaterialIconsProps, MaterialCommunityIconsProps> & {
|
|
14
|
+
style?: Style;
|
|
15
|
+
className?: string;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export type { IconProps };
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { Pressable, View } from 'react-native';
|
|
2
|
+
import Animated, { LayoutAnimationConfig, ZoomInRotate } from 'react-native-reanimated';
|
|
3
|
+
|
|
4
|
+
import { Icon } from '@/components/nativewindui/Icon';
|
|
5
|
+
import { cn } from '@/lib/cn';
|
|
6
|
+
import { useColorScheme } from '@/lib/useColorScheme';
|
|
7
|
+
import { COLORS } from '@/theme/colors';
|
|
8
|
+
|
|
9
|
+
export function ThemeToggle() {
|
|
10
|
+
const { colorScheme, toggleColorScheme } = useColorScheme();
|
|
11
|
+
return (
|
|
12
|
+
<LayoutAnimationConfig skipEntering>
|
|
13
|
+
<Animated.View
|
|
14
|
+
className="items-center justify-center"
|
|
15
|
+
key={`toggle-${colorScheme}`}
|
|
16
|
+
entering={ZoomInRotate}>
|
|
17
|
+
<Pressable onPress={toggleColorScheme} className="opacity-80">
|
|
18
|
+
{colorScheme === 'dark'
|
|
19
|
+
? ({ pressed }) => (
|
|
20
|
+
<View className={cn('px-0.5', pressed && 'opacity-50')}>
|
|
21
|
+
<Icon name="moon.stars" color={COLORS.white} />
|
|
22
|
+
</View>
|
|
23
|
+
)
|
|
24
|
+
: ({ pressed }) => (
|
|
25
|
+
<View className={cn('px-0.5', pressed && 'opacity-50')}>
|
|
26
|
+
<Icon name="sun.min" color={COLORS.black} />
|
|
27
|
+
</View>
|
|
28
|
+
)}
|
|
29
|
+
</Pressable>
|
|
30
|
+
</Animated.View>
|
|
31
|
+
</LayoutAnimationConfig>
|
|
32
|
+
);
|
|
33
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Tabs } from 'expo-router';
|
|
2
|
+
|
|
3
|
+
import { TabBarIcon } from '@/components/TabBarIcon';
|
|
4
|
+
|
|
5
|
+
export default function TabLayout() {
|
|
6
|
+
return (
|
|
7
|
+
<Tabs
|
|
8
|
+
screenOptions={{
|
|
9
|
+
headerShown: false,
|
|
10
|
+
tabBarActiveTintColor: 'black',
|
|
11
|
+
}}>
|
|
12
|
+
<Tabs.Screen
|
|
13
|
+
name="index"
|
|
14
|
+
options={{
|
|
15
|
+
title: 'Tab One',
|
|
16
|
+
tabBarIcon: ({ color }) => <TabBarIcon name="code" color={color} />,
|
|
17
|
+
}}
|
|
18
|
+
/>
|
|
19
|
+
<Tabs.Screen
|
|
20
|
+
name="two"
|
|
21
|
+
options={{
|
|
22
|
+
title: 'Tab Two',
|
|
23
|
+
tabBarIcon: ({ color }) => <TabBarIcon name="code" color={color} />,
|
|
24
|
+
}}
|
|
25
|
+
/>
|
|
26
|
+
</Tabs>
|
|
27
|
+
);
|
|
28
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Stack } from 'expo-router';
|
|
2
|
+
|
|
3
|
+
import { Container } from '@/components/Container';
|
|
4
|
+
import { ScreenContent } from '@/components/ScreenContent';
|
|
5
|
+
|
|
6
|
+
export default function Home() {
|
|
7
|
+
return (
|
|
8
|
+
<>
|
|
9
|
+
<Stack.Screen options={{ title: 'Tab One' }} />
|
|
10
|
+
<Container>
|
|
11
|
+
<ScreenContent path="app/(drawer)/(tabs)/index.tsx" title="Tab One" />
|
|
12
|
+
</Container>
|
|
13
|
+
</>
|
|
14
|
+
);
|
|
15
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Stack } from 'expo-router';
|
|
2
|
+
|
|
3
|
+
import { Container } from '@/components/Container';
|
|
4
|
+
import { ScreenContent } from '@/components/ScreenContent';
|
|
5
|
+
|
|
6
|
+
export default function Home() {
|
|
7
|
+
return (
|
|
8
|
+
<>
|
|
9
|
+
<Stack.Screen options={{ title: 'Tab Two' }} />
|
|
10
|
+
<Container>
|
|
11
|
+
<ScreenContent path="app/(drawer)/(tabs)/two.tsx" title="Tab Two" />
|
|
12
|
+
</Container>
|
|
13
|
+
</>
|
|
14
|
+
);
|
|
15
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Ionicons, MaterialIcons } from '@expo/vector-icons';
|
|
2
|
+
import { Link } from 'expo-router';
|
|
3
|
+
import { Drawer } from 'expo-router/drawer';
|
|
4
|
+
|
|
5
|
+
import { HeaderButton } from '../../components/HeaderButton';
|
|
6
|
+
|
|
7
|
+
const DrawerLayout = () => (
|
|
8
|
+
<Drawer>
|
|
9
|
+
<Drawer.Screen
|
|
10
|
+
name="index"
|
|
11
|
+
options={{
|
|
12
|
+
headerTitle: 'Home',
|
|
13
|
+
drawerLabel: 'Home',
|
|
14
|
+
drawerIcon: ({ size, color }) => <Ionicons name="home-outline" size={size} color={color} />,
|
|
15
|
+
}}
|
|
16
|
+
/>
|
|
17
|
+
<Drawer.Screen
|
|
18
|
+
name="(tabs)"
|
|
19
|
+
options={{
|
|
20
|
+
headerTitle: 'Tabs',
|
|
21
|
+
drawerLabel: 'Tabs',
|
|
22
|
+
drawerIcon: ({ size, color }) => (
|
|
23
|
+
<MaterialIcons name="border-bottom" size={size} color={color} />
|
|
24
|
+
),
|
|
25
|
+
headerRight: () => (
|
|
26
|
+
<Link href="/modal" asChild>
|
|
27
|
+
<HeaderButton />
|
|
28
|
+
</Link>
|
|
29
|
+
),
|
|
30
|
+
}}
|
|
31
|
+
/>
|
|
32
|
+
</Drawer>
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
export default DrawerLayout;
|