create-expo-stack 2.21.3 → 2.23.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 +37 -23
- package/build/cli.js +5 -6
- package/build/commands/create-expo-stack.js +19 -7
- package/build/templates/base/.gitignore.ejs +1 -3
- package/build/templates/base/App.tsx.ejs +6 -4
- package/build/templates/base/app.json.ejs +18 -9
- package/build/templates/base/components/Container.tsx.ejs +2 -1
- package/build/templates/base/css-env.d.ts.ejs +1 -0
- package/build/templates/base/eslint.config.js.ejs +1 -2
- package/build/templates/base/package.json.ejs +49 -30
- package/build/templates/base/tsconfig.json.ejs +9 -4
- package/build/templates/packages/expo-router/drawer/app/_layout.tsx.ejs +5 -3
- package/build/templates/packages/expo-router/drawer/app/modal.tsx.ejs +1 -1
- package/build/templates/packages/expo-router/stack/app/_layout.tsx.ejs +5 -3
- package/build/templates/packages/expo-router/stack/app/index.tsx.ejs +1 -1
- package/build/templates/packages/expo-router/tabs/app/_layout.tsx.ejs +5 -3
- package/build/templates/packages/expo-router/tabs/app/modal.tsx.ejs +1 -1
- package/build/templates/packages/i18next/translation/index.ts.ejs +3 -3
- package/build/templates/packages/nativewindui/components/Container.tsx.ejs +2 -1
- package/build/templates/packages/nativewindui/components/TabBarIcon.tsx.ejs +2 -2
- package/build/templates/packages/nativewindui/components/nativewindui/Icon/Icon.ios.tsx.ejs +7 -4
- package/build/templates/packages/nativewindui/components/nativewindui/Icon/types.ts.ejs +4 -3
- package/build/templates/packages/nativewindui/drawer/app/(drawer)/index.tsx.ejs +7 -7
- package/build/templates/packages/nativewindui/drawer/app/_layout.tsx.ejs +4 -5
- package/build/templates/packages/nativewindui/drawer/app/modal.tsx.ejs +2 -2
- package/build/templates/packages/nativewindui/lib/useHeaderSearchBar.tsx.ejs +33 -0
- package/build/templates/packages/nativewindui/stack/app/_layout.tsx.ejs +1 -1
- package/build/templates/packages/nativewindui/stack/app/index.tsx.ejs +9 -39
- package/build/templates/packages/nativewindui/tabs/app/(tabs)/index.tsx.ejs +10 -13
- package/build/templates/packages/nativewindui/tabs/app/_layout.tsx.ejs +5 -9
- package/build/templates/packages/nativewindui/tabs/app/modal.tsx.ejs +1 -1
- package/build/templates/packages/nativewindui/theme/index.ts.ejs +1 -1
- package/build/templates/packages/react-navigation/App.tsx.ejs +5 -3
- package/build/templates/packages/react-navigation/screens/modal.tsx.ejs +1 -1
- package/build/templates/packages/react-navigation/screens/overview.tsx.ejs +1 -1
- package/build/types/types.d.ts +3 -2
- package/build/types/utilities/generateProjectFiles.d.ts +2 -0
- package/build/types/utilities/softwareMansion.d.ts +13 -0
- package/build/types/utilities/systemCommand.d.ts +3 -1
- package/build/types.js +10 -2
- package/build/utilities/clearNavigationPackages.js +2 -2
- package/build/utilities/clearStylingPackages.js +2 -2
- package/build/utilities/configAnalytics.js +2 -3
- package/build/utilities/configureProjectFiles.js +6 -4
- package/build/utilities/copyBaseAssets.js +2 -3
- package/build/utilities/generateNWUI.js +106 -3
- package/build/utilities/generateProjectFiles.js +25 -3
- package/build/utilities/getPackageManager.js +5 -6
- package/build/utilities/printOutput.js +54 -19
- package/build/utilities/renderTitle.js +2 -3
- package/build/utilities/runCLI.js +62 -3
- package/build/utilities/runEasConfigure.js +2 -3
- package/build/utilities/runIgnite.js +2 -3
- package/build/utilities/showHelp.js +8 -3
- package/build/utilities/softwareMansion.js +48 -0
- package/build/utilities/systemCommand.js +13 -5
- package/build/utilities/usePackage.js +2 -3
- package/build/utilities/validateProjectName.js +2 -3
- package/package.json +1 -1
|
@@ -3,17 +3,20 @@
|
|
|
3
3
|
"compilerOptions": {
|
|
4
4
|
<% if (props.flags.importAlias) { %>
|
|
5
5
|
"strict": true,
|
|
6
|
+
<% if (props.navigationPackage?.name !== 'expo-router') { %>
|
|
7
|
+
"ignoreDeprecations": "6.0",
|
|
6
8
|
"baseUrl": ".",
|
|
9
|
+
<% } %>
|
|
7
10
|
"paths": {
|
|
8
11
|
<% if (props.stylingPackage?.name === 'nativewindui') { %>
|
|
9
12
|
"@/*": [ "./*" ]
|
|
10
13
|
<% } else { %>
|
|
11
14
|
<% if (props.navigationPackage?.name === "expo-router" && props.flags.importAlias === true) { %>
|
|
12
|
-
"@/*": ["
|
|
15
|
+
"@/*": ["./*"]
|
|
13
16
|
<% } else if (props.flags.importAlias === true) { %>
|
|
14
|
-
"@/*": ["src/*"]
|
|
17
|
+
"@/*": ["./src/*"]
|
|
15
18
|
<% } else { %>
|
|
16
|
-
"<%= props.flags.importAlias %>": ["src/*"]
|
|
19
|
+
"<%= props.flags.importAlias %>": ["./src/*"]
|
|
17
20
|
<% } %>
|
|
18
21
|
<% } %>
|
|
19
22
|
}
|
|
@@ -28,9 +31,11 @@
|
|
|
28
31
|
".expo/types/**/*.ts",
|
|
29
32
|
<% if (props.stylingPackage?.name === 'nativewind' || props.stylingPackage?.name === 'nativewindui') { %>
|
|
30
33
|
"expo-env.d.ts",
|
|
34
|
+
"css-env.d.ts",
|
|
31
35
|
"nativewind-env.d.ts"
|
|
32
36
|
<% } else { %>
|
|
33
|
-
"expo-env.d.ts"
|
|
37
|
+
"expo-env.d.ts",
|
|
38
|
+
"css-env.d.ts"
|
|
34
39
|
<% } %>
|
|
35
40
|
]
|
|
36
41
|
<% } else { %>
|
|
@@ -19,9 +19,11 @@ import { Stack } from 'expo-router';
|
|
|
19
19
|
<% } %>
|
|
20
20
|
|
|
21
21
|
<% if (props.analyticsPackage?.name === "vexo-analytics") { %>
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
const vexoApiKey = process.env.EXPO_PUBLIC_VEXO_API_KEY;
|
|
23
|
+
if (vexoApiKey) {
|
|
24
|
+
const { vexo } = require('vexo-analytics');
|
|
25
|
+
vexo(vexoApiKey);
|
|
26
|
+
}
|
|
25
27
|
<% } %>
|
|
26
28
|
|
|
27
29
|
export const unstable_settings = {
|
|
@@ -4,7 +4,7 @@ import { Platform } from 'react-native';
|
|
|
4
4
|
import { ScreenContent } from '@/components/ScreenContent';
|
|
5
5
|
|
|
6
6
|
<% if (props.internalizationPackage?.name === "i18next") { %>
|
|
7
|
-
import { InternalizationExample } from 'components/InternalizationExample';
|
|
7
|
+
import { InternalizationExample } from '../components/InternalizationExample';
|
|
8
8
|
<% } %>
|
|
9
9
|
|
|
10
10
|
export default function Modal() {
|
|
@@ -12,9 +12,11 @@
|
|
|
12
12
|
import { Stack } from "expo-router";
|
|
13
13
|
|
|
14
14
|
<% if (props.analyticsPackage?.name === "vexo-analytics") { %>
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
const vexoApiKey = process.env.EXPO_PUBLIC_VEXO_API_KEY;
|
|
16
|
+
if (vexoApiKey) {
|
|
17
|
+
const { vexo } = require('vexo-analytics');
|
|
18
|
+
vexo(vexoApiKey);
|
|
19
|
+
}
|
|
18
20
|
<% } %>
|
|
19
21
|
|
|
20
22
|
export default function Layout() {
|
|
@@ -13,7 +13,7 @@ import { Container } from '@/components/Container';
|
|
|
13
13
|
import { ScreenContent } from '@/components/ScreenContent';
|
|
14
14
|
|
|
15
15
|
<% if (props.internalizationPackage?.name === "i18next") { %>
|
|
16
|
-
import { InternalizationExample } from 'components/InternalizationExample';
|
|
16
|
+
import { InternalizationExample } from '../components/InternalizationExample';
|
|
17
17
|
<% } %>
|
|
18
18
|
|
|
19
19
|
export default function Home() {
|
|
@@ -13,9 +13,11 @@
|
|
|
13
13
|
import { Stack } from "expo-router";
|
|
14
14
|
|
|
15
15
|
<% if (props.analyticsPackage?.name === "vexo-analytics") { %>
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
const vexoApiKey = process.env.EXPO_PUBLIC_VEXO_API_KEY;
|
|
17
|
+
if (vexoApiKey) {
|
|
18
|
+
const { vexo } = require('vexo-analytics');
|
|
19
|
+
vexo(vexoApiKey);
|
|
20
|
+
}
|
|
19
21
|
<% } %>
|
|
20
22
|
|
|
21
23
|
export const unstable_settings = {
|
|
@@ -4,7 +4,7 @@ import { Platform } from 'react-native';
|
|
|
4
4
|
import { ScreenContent } from '@/components/ScreenContent';
|
|
5
5
|
|
|
6
6
|
<% if (props.internalizationPackage?.name === "i18next") { %>
|
|
7
|
-
import { InternalizationExample } from 'components/InternalizationExample';
|
|
7
|
+
import { InternalizationExample } from '../components/InternalizationExample';
|
|
8
8
|
<% } %>
|
|
9
9
|
|
|
10
10
|
export default function Modal() {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { init18n } from 'core/i18n/init';
|
|
2
|
-
import en from '
|
|
3
|
-
import fr from '
|
|
1
|
+
import { init18n } from '../core/i18n/init';
|
|
2
|
+
import en from './en.json';
|
|
3
|
+
import fr from './fr.json';
|
|
4
4
|
|
|
5
5
|
export const resources = {
|
|
6
6
|
en: {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { StyleSheet
|
|
1
|
+
import { StyleSheet } from 'react-native';
|
|
2
|
+
import { SafeAreaView } from 'react-native-safe-area-context';
|
|
2
3
|
|
|
3
4
|
export const Container = ({ children }: { children: React.ReactNode }) => {
|
|
4
5
|
return <SafeAreaView style={styles.container}>{children}</SafeAreaView>;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import FontAwesome from '@expo/vector-icons/FontAwesome';
|
|
2
|
-
import { StyleSheet } from 'react-native';
|
|
2
|
+
import { ColorValue, StyleSheet } from 'react-native';
|
|
3
3
|
|
|
4
4
|
export const TabBarIcon = (props: {
|
|
5
5
|
name: React.ComponentProps<typeof FontAwesome>['name'];
|
|
6
|
-
color:
|
|
6
|
+
color: ColorValue;
|
|
7
7
|
}) => {
|
|
8
8
|
return <FontAwesome size={28} style={styles.tabBarIcon} {...props} />;
|
|
9
9
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { SymbolView } from 'expo-symbols';
|
|
2
|
+
import type { ComponentProps } from 'react';
|
|
2
3
|
|
|
3
4
|
import type { IconProps } from './types';
|
|
4
5
|
|
|
@@ -14,14 +15,16 @@ function Icon({
|
|
|
14
15
|
...props
|
|
15
16
|
}: IconProps) {
|
|
16
17
|
const { colors } = useColorScheme();
|
|
18
|
+
const symbolName = (name ?? 'questionmark') as ComponentProps<typeof SymbolView>['name'];
|
|
19
|
+
|
|
17
20
|
return (
|
|
18
21
|
<SymbolView
|
|
19
|
-
|
|
22
|
+
{...props}
|
|
23
|
+
{...sfSymbol}
|
|
24
|
+
name={symbolName}
|
|
20
25
|
tintColor={rgbaToHex(color ?? colors.foreground)}
|
|
21
26
|
size={size}
|
|
22
27
|
resizeMode="scaleAspectFit"
|
|
23
|
-
{...props}
|
|
24
|
-
{...sfSymbol}
|
|
25
28
|
/>
|
|
26
29
|
);
|
|
27
30
|
}
|
|
@@ -49,4 +52,4 @@ function rgbaToHex(color: string): string {
|
|
|
49
52
|
const toHex = (n: number) => n.toString(16).padStart(2, '0');
|
|
50
53
|
|
|
51
54
|
return `#${toHex(r)}${toHex(g)}${toHex(b)}${a < 255 ? toHex(a) : ''}`;
|
|
52
|
-
}
|
|
55
|
+
}
|
|
@@ -5,14 +5,15 @@ import type { IconMapper } from 'rn-icon-mapper';
|
|
|
5
5
|
|
|
6
6
|
type MaterialCommunityIconsProps = React.ComponentProps<typeof MaterialCommunityIcons>;
|
|
7
7
|
type MaterialIconsProps = React.ComponentProps<typeof MaterialIcons>;
|
|
8
|
+
type SymbolIconProps = Omit<SymbolViewProps, 'name'> & { name: string };
|
|
8
9
|
|
|
9
|
-
type Style =
|
|
10
|
+
type Style = SymbolIconProps['style'] &
|
|
10
11
|
MaterialIconsProps['style'] &
|
|
11
12
|
MaterialCommunityIconsProps['style'];
|
|
12
13
|
|
|
13
|
-
type IconProps = IconMapper<
|
|
14
|
+
type IconProps = IconMapper<SymbolIconProps, MaterialIconsProps, MaterialCommunityIconsProps> & {
|
|
14
15
|
style?: Style;
|
|
15
16
|
className?: string;
|
|
16
17
|
};
|
|
17
18
|
|
|
18
|
-
export type { IconProps };
|
|
19
|
+
export type { IconProps };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Stack } from 'expo-router';
|
|
2
|
-
import { useHeaderHeight } from '
|
|
2
|
+
import { useHeaderHeight } from 'expo-router/react-navigation';
|
|
3
3
|
import { FlashList } from '@shopify/flash-list';
|
|
4
4
|
import { cssInterop } from 'nativewind';
|
|
5
5
|
import * as React from 'react';
|
|
@@ -27,12 +27,12 @@ import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
|
27
27
|
<% if (props.stylingPackage?.options.selectedComponents.includes('action-sheet')) { %>
|
|
28
28
|
import { useActionSheet } from '@expo/react-native-action-sheet';
|
|
29
29
|
<% } %>
|
|
30
|
-
import { Icon } from '@roninoss/icons';
|
|
31
30
|
<% if (props.stylingPackage?.options.selectedComponents.includes('ratings-indicator')) { %>
|
|
32
31
|
import * as StoreReview from 'expo-store-review';
|
|
33
32
|
<% } %>
|
|
34
33
|
|
|
35
34
|
import { Container } from '@/components/Container';
|
|
35
|
+
import { Icon } from '@/components/nativewindui/Icon';
|
|
36
36
|
<% if (props.stylingPackage?.options.selectedComponents.includes('activity-indicator')) { %>
|
|
37
37
|
import { ActivityIndicator } from '@/components/nativewindui/ActivityIndicator';
|
|
38
38
|
<% } %>
|
|
@@ -59,6 +59,7 @@ import { Text } from '@/components/nativewindui/Text';
|
|
|
59
59
|
import { Toggle } from '@/components/nativewindui/Toggle';
|
|
60
60
|
<% } %>
|
|
61
61
|
import { useColorScheme } from '@/lib/useColorScheme';
|
|
62
|
+
import { useHeaderSearchBar } from '@/lib/useHeaderSearchBar';
|
|
62
63
|
|
|
63
64
|
export default function Home() {
|
|
64
65
|
const searchValue = useHeaderSearchBar({ hideWhenScrolling: COMPONENTS.length === 0 });
|
|
@@ -75,7 +76,6 @@ export default function Home() {
|
|
|
75
76
|
contentInsetAdjustmentBehavior="automatic"
|
|
76
77
|
keyboardShouldPersistTaps="handled"
|
|
77
78
|
data={data}
|
|
78
|
-
estimatedItemSize={200}
|
|
79
79
|
contentContainerClassName="py-4 android:pb-12"
|
|
80
80
|
extraData={searchValue}
|
|
81
81
|
keyExtractor={keyExtractor}
|
|
@@ -112,7 +112,7 @@ function ListEmptyComponent() {
|
|
|
112
112
|
|
|
113
113
|
return (
|
|
114
114
|
<View style={{ height }} className="flex-1 items-center justify-center gap-1 px-12">
|
|
115
|
-
<Icon name="
|
|
115
|
+
<Icon name="doc.badge.plus" size={42} color={colors.grey} />
|
|
116
116
|
<Text variant='title3' className='pb-1 text-center font-semibold'>
|
|
117
117
|
No Components Installed
|
|
118
118
|
</Text>
|
|
@@ -226,8 +226,8 @@ const COMPONENTS: ComponentItem[] = [
|
|
|
226
226
|
<DatePicker
|
|
227
227
|
value={date}
|
|
228
228
|
mode='datetime'
|
|
229
|
-
|
|
230
|
-
setDate(
|
|
229
|
+
onValueChange={(_event, selectedDate) => {
|
|
230
|
+
setDate(selectedDate);
|
|
231
231
|
}}
|
|
232
232
|
/>
|
|
233
233
|
</View>
|
|
@@ -532,4 +532,4 @@ const COMPONENTS: ComponentItem[] = [
|
|
|
532
532
|
},
|
|
533
533
|
},
|
|
534
534
|
<% } %>
|
|
535
|
-
];
|
|
535
|
+
];
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import '../global.css';
|
|
2
2
|
import 'expo-dev-client';
|
|
3
|
-
import { ThemeProvider as NavThemeProvider } from '
|
|
3
|
+
import { ThemeProvider as NavThemeProvider } from 'expo-router/react-navigation';
|
|
4
4
|
<% if (props.stylingPackage?.options.selectedComponents.includes('action-sheet')) { %>
|
|
5
5
|
import { ActionSheetProvider } from '@expo/react-native-action-sheet';
|
|
6
6
|
<% } %>
|
|
@@ -13,8 +13,8 @@ import { StatusBar } from 'expo-status-bar';
|
|
|
13
13
|
import { GestureHandlerRootView } from 'react-native-gesture-handler';
|
|
14
14
|
<% } %>
|
|
15
15
|
|
|
16
|
-
import { ThemeToggle } from '@/components/ThemeToggle';
|
|
17
|
-
import { useColorScheme
|
|
16
|
+
import { ThemeToggle } from '@/components/nativewindui/ThemeToggle';
|
|
17
|
+
import { useColorScheme } from '@/lib/useColorScheme';
|
|
18
18
|
import { NAV_THEME } from '@/theme';
|
|
19
19
|
|
|
20
20
|
export {
|
|
@@ -23,7 +23,6 @@ export {
|
|
|
23
23
|
} from 'expo-router';
|
|
24
24
|
|
|
25
25
|
export default function RootLayout() {
|
|
26
|
-
useInitialAndroidBarSync();
|
|
27
26
|
const { colorScheme, isDarkColorScheme } = useColorScheme();
|
|
28
27
|
|
|
29
28
|
return (
|
|
@@ -72,4 +71,4 @@ const MODAL_OPTIONS = {
|
|
|
72
71
|
animation: 'fade_from_bottom', // for android
|
|
73
72
|
title: 'Settings',
|
|
74
73
|
headerRight: () => <ThemeToggle />,
|
|
75
|
-
} as const;
|
|
74
|
+
} as const;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { Icon } from '@roninoss/icons';
|
|
2
1
|
import { StatusBar } from 'expo-status-bar';
|
|
3
2
|
import { Linking, Platform, View } from 'react-native';
|
|
4
3
|
|
|
4
|
+
import { Icon } from '@/components/nativewindui/Icon';
|
|
5
5
|
import { Text } from '@/components/nativewindui/Text';
|
|
6
6
|
import { useColorScheme } from '@/lib/useColorScheme';
|
|
7
7
|
|
|
@@ -13,7 +13,7 @@ export default function ModalScreen() {
|
|
|
13
13
|
style={Platform.OS === 'ios' ? 'light' : colorScheme === 'dark' ? 'light' : 'dark'}
|
|
14
14
|
/>
|
|
15
15
|
<View className="flex-1 items-center justify-center gap-1 px-12">
|
|
16
|
-
<Icon name="
|
|
16
|
+
<Icon name="doc.badge.plus" size={42} color={colors.grey} />
|
|
17
17
|
<Text variant="title3" className="pb-1 text-center font-semibold">
|
|
18
18
|
NativewindUI
|
|
19
19
|
</Text>
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { useNavigation } from 'expo-router/react-navigation';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import type { SearchBarProps } from 'react-native-screens';
|
|
4
|
+
|
|
5
|
+
import { useColorScheme } from './useColorScheme';
|
|
6
|
+
|
|
7
|
+
function useHeaderSearchBar(props: SearchBarProps = {}) {
|
|
8
|
+
const { colorScheme, colors } = useColorScheme();
|
|
9
|
+
const navigation = useNavigation();
|
|
10
|
+
const [search, setSearch] = React.useState('');
|
|
11
|
+
|
|
12
|
+
React.useLayoutEffect(() => {
|
|
13
|
+
navigation.setOptions({
|
|
14
|
+
headerSearchBarOptions: {
|
|
15
|
+
placeholder: 'Search...',
|
|
16
|
+
textColor: colors.foreground,
|
|
17
|
+
tintColor: colors.primary,
|
|
18
|
+
headerIconColor: colors.foreground,
|
|
19
|
+
hintTextColor: colors.grey,
|
|
20
|
+
hideWhenScrolling: false,
|
|
21
|
+
onChangeText(event) {
|
|
22
|
+
setSearch(event.nativeEvent.text);
|
|
23
|
+
},
|
|
24
|
+
...props,
|
|
25
|
+
} satisfies SearchBarProps,
|
|
26
|
+
});
|
|
27
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
28
|
+
}, [navigation, colorScheme]);
|
|
29
|
+
|
|
30
|
+
return search;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export { useHeaderSearchBar };
|
|
@@ -3,7 +3,7 @@ import '@/global.css';
|
|
|
3
3
|
<% if (props.stylingPackage?.options.selectedComponents.includes('action-sheet')) { %>
|
|
4
4
|
import { ActionSheetProvider } from '@expo/react-native-action-sheet';
|
|
5
5
|
<% } %>
|
|
6
|
-
import { ThemeProvider as NavThemeProvider } from '
|
|
6
|
+
import { ThemeProvider as NavThemeProvider } from 'expo-router/react-navigation';
|
|
7
7
|
import * as Device from 'expo-device';
|
|
8
8
|
import { Link, Stack } from 'expo-router';
|
|
9
9
|
import { StatusBar } from 'expo-status-bar';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useHeaderHeight } from '
|
|
1
|
+
import { useHeaderHeight } from 'expo-router/react-navigation';
|
|
2
2
|
import { FlashList } from '@shopify/flash-list';
|
|
3
3
|
import { cssInterop } from 'nativewind';
|
|
4
4
|
import * as React from 'react';
|
|
@@ -21,11 +21,9 @@ import {
|
|
|
21
21
|
View,
|
|
22
22
|
} from 'react-native';
|
|
23
23
|
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
24
|
-
import { SearchBarProps } from 'react-native-screens';
|
|
25
24
|
<% if (props.stylingPackage?.options.selectedComponents.includes('action-sheet')) { %>
|
|
26
25
|
import { useActionSheet } from '@expo/react-native-action-sheet';
|
|
27
26
|
<% } %>
|
|
28
|
-
import { useNavigation } from '@react-navigation/native';
|
|
29
27
|
<% if (props.stylingPackage?.options.selectedComponents.includes('button')) { %>
|
|
30
28
|
import * as Haptics from 'expo-haptics';
|
|
31
29
|
<% } else { %>
|
|
@@ -64,6 +62,7 @@ import { Text } from '@/components/nativewindui/Text';
|
|
|
64
62
|
<% if (props.stylingPackage?.options.selectedComponents.includes('toggle')) { %>
|
|
65
63
|
import { Toggle } from '@/components/nativewindui/Toggle';
|
|
66
64
|
<% } %>
|
|
65
|
+
import { useHeaderSearchBar } from '@/lib/useHeaderSearchBar';
|
|
67
66
|
import { useColorScheme } from '@/lib/useColorScheme';
|
|
68
67
|
import { COLORS } from '@/theme/colors';
|
|
69
68
|
|
|
@@ -95,32 +94,6 @@ export default function Screen() {
|
|
|
95
94
|
);
|
|
96
95
|
}
|
|
97
96
|
|
|
98
|
-
function useHeaderSearchBar(props: SearchBarProps = {}) {
|
|
99
|
-
const { colorScheme, colors } = useColorScheme();
|
|
100
|
-
const navigation = useNavigation();
|
|
101
|
-
const [search, setSearch] = React.useState('');
|
|
102
|
-
|
|
103
|
-
React.useLayoutEffect(() => {
|
|
104
|
-
navigation.setOptions({
|
|
105
|
-
headerSearchBarOptions: {
|
|
106
|
-
placeholder: 'Search...',
|
|
107
|
-
textColor: colors.foreground,
|
|
108
|
-
tintColor: colors.primary,
|
|
109
|
-
headerIconColor: colors.foreground,
|
|
110
|
-
hintTextColor: colors.grey,
|
|
111
|
-
hideWhenScrolling: false,
|
|
112
|
-
onChangeText(ev) {
|
|
113
|
-
setSearch(ev.nativeEvent.text);
|
|
114
|
-
},
|
|
115
|
-
...props,
|
|
116
|
-
} satisfies SearchBarProps,
|
|
117
|
-
});
|
|
118
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
119
|
-
}, [navigation, colorScheme]);
|
|
120
|
-
|
|
121
|
-
return search;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
97
|
function ListEmptyComponent() {
|
|
125
98
|
const insets = useSafeAreaInsets();
|
|
126
99
|
const dimensions = useWindowDimensions();
|
|
@@ -315,16 +288,13 @@ const COMPONENTS: ComponentItem[] = [
|
|
|
315
288
|
name: 'Progress Indicator',
|
|
316
289
|
component: function ProgressIndicatorExample() {
|
|
317
290
|
const [progress, setProgress] = React.useState(13);
|
|
291
|
+
React.useEffect(() => {
|
|
292
|
+
const intervalId = setInterval(() => {
|
|
293
|
+
setProgress((prev) => (prev >= 99 ? 0 : prev + 5));
|
|
294
|
+
}, 1000);
|
|
318
295
|
|
|
319
|
-
React.useEffect(() => {
|
|
320
|
-
let id: ReturnType<typeof setInterval> | null = null;
|
|
321
|
-
if (!id) {
|
|
322
|
-
id = setInterval(() => {
|
|
323
|
-
setProgress((prev) => (prev >= 99 ? 0 : prev + 5));
|
|
324
|
-
}, 1000);
|
|
325
|
-
}
|
|
326
296
|
return () => {
|
|
327
|
-
|
|
297
|
+
clearInterval(intervalId);
|
|
328
298
|
};
|
|
329
299
|
}, []);
|
|
330
300
|
return (
|
|
@@ -378,8 +348,8 @@ const COMPONENTS: ComponentItem[] = [
|
|
|
378
348
|
<DatePicker
|
|
379
349
|
value={date}
|
|
380
350
|
mode='datetime'
|
|
381
|
-
|
|
382
|
-
setDate(
|
|
351
|
+
onValueChange={(_event, selectedDate) => {
|
|
352
|
+
setDate(selectedDate);
|
|
383
353
|
}}
|
|
384
354
|
/>
|
|
385
355
|
</View>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Stack } from 'expo-router';
|
|
2
|
-
import { useHeaderHeight } from '
|
|
2
|
+
import { useHeaderHeight } from 'expo-router/react-navigation';
|
|
3
3
|
import { FlashList } from '@shopify/flash-list';
|
|
4
4
|
import { cssInterop } from 'nativewind';
|
|
5
5
|
import * as React from 'react';
|
|
@@ -27,12 +27,12 @@ import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
|
27
27
|
<% if (props.stylingPackage?.options.selectedComponents.includes('action-sheet')) { %>
|
|
28
28
|
import { useActionSheet } from '@expo/react-native-action-sheet';
|
|
29
29
|
<% } %>
|
|
30
|
-
import { Icon } from '@roninoss/icons';
|
|
31
30
|
<% if (props.stylingPackage?.options.selectedComponents.includes('ratings-indicator')) { %>
|
|
32
31
|
import * as StoreReview from 'expo-store-review';
|
|
33
32
|
<% } %>
|
|
34
33
|
|
|
35
34
|
import { Container } from '@/components/Container';
|
|
35
|
+
import { Icon } from '@/components/nativewindui/Icon';
|
|
36
36
|
<% if (props.stylingPackage?.options.selectedComponents.includes('activity-indicator')) { %>
|
|
37
37
|
import { ActivityIndicator } from '@/components/nativewindui/ActivityIndicator';
|
|
38
38
|
<% } %>
|
|
@@ -76,7 +76,6 @@ export default function Home() {
|
|
|
76
76
|
contentInsetAdjustmentBehavior="automatic"
|
|
77
77
|
keyboardShouldPersistTaps="handled"
|
|
78
78
|
data={data}
|
|
79
|
-
estimatedItemSize={200}
|
|
80
79
|
contentContainerClassName="py-4 android:pb-12"
|
|
81
80
|
extraData={searchValue}
|
|
82
81
|
keyExtractor={keyExtractor}
|
|
@@ -113,7 +112,7 @@ function ListEmptyComponent() {
|
|
|
113
112
|
|
|
114
113
|
return (
|
|
115
114
|
<View style={{ height }} className="flex-1 items-center justify-center gap-1 px-12">
|
|
116
|
-
<Icon name="
|
|
115
|
+
<Icon name="doc.badge.plus" size={42} color={colors.grey} />
|
|
117
116
|
<Text variant='title3' className='pb-1 text-center font-semibold'>
|
|
118
117
|
No Components Installed
|
|
119
118
|
</Text>
|
|
@@ -227,8 +226,8 @@ const COMPONENTS: ComponentItem[] = [
|
|
|
227
226
|
<DatePicker
|
|
228
227
|
value={date}
|
|
229
228
|
mode='datetime'
|
|
230
|
-
|
|
231
|
-
setDate(
|
|
229
|
+
onValueChange={(_event, selectedDate) => {
|
|
230
|
+
setDate(selectedDate);
|
|
232
231
|
}}
|
|
233
232
|
/>
|
|
234
233
|
</View>
|
|
@@ -263,15 +262,13 @@ const COMPONENTS: ComponentItem[] = [
|
|
|
263
262
|
name: 'Progress Indicator',
|
|
264
263
|
component: function ProgressIndicatorExample() {
|
|
265
264
|
const [progress, setProgress] = React.useState(13);
|
|
266
|
-
let id: ReturnType<typeof setInterval> | null = null;
|
|
267
265
|
React.useEffect(() => {
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
}
|
|
266
|
+
const intervalId = setInterval(() => {
|
|
267
|
+
setProgress((prev) => (prev >= 99 ? 0 : prev + 5));
|
|
268
|
+
}, 1000);
|
|
269
|
+
|
|
273
270
|
return () => {
|
|
274
|
-
|
|
271
|
+
clearInterval(intervalId);
|
|
275
272
|
};
|
|
276
273
|
}, []);
|
|
277
274
|
return (
|
|
@@ -1,23 +1,20 @@
|
|
|
1
1
|
import '../global.css';
|
|
2
2
|
import 'expo-dev-client';
|
|
3
|
-
import { ThemeProvider as NavThemeProvider } from '
|
|
4
|
-
import { Icon } from '@roninoss/icons';
|
|
3
|
+
import { ThemeProvider as NavThemeProvider } from 'expo-router/react-navigation';
|
|
5
4
|
<% if (props.stylingPackage?.options.selectedComponents.includes('action-sheet')) { %>
|
|
6
5
|
import { ActionSheetProvider } from '@expo/react-native-action-sheet';
|
|
7
6
|
<% } %>
|
|
8
7
|
<% if (props.stylingPackage?.options.selectedComponents.includes('bottom-sheet')) { %>
|
|
9
8
|
import { BottomSheetModalProvider } from '@gorhom/bottom-sheet';
|
|
10
9
|
<% } %>
|
|
11
|
-
import {
|
|
10
|
+
import { Stack } from 'expo-router';
|
|
12
11
|
import { StatusBar } from 'expo-status-bar';
|
|
13
|
-
import { Pressable, View } from 'react-native';
|
|
14
12
|
<% if (props.stylingPackage?.options.selectedComponents.includes('bottom-sheet')) { %>
|
|
15
13
|
import { GestureHandlerRootView } from 'react-native-gesture-handler';
|
|
16
14
|
<% } %>
|
|
17
15
|
|
|
18
|
-
import { ThemeToggle } from '@/components/ThemeToggle';
|
|
19
|
-
import {
|
|
20
|
-
import { useColorScheme, useInitialAndroidBarSync } from '@/lib/useColorScheme';
|
|
16
|
+
import { ThemeToggle } from '@/components/nativewindui/ThemeToggle';
|
|
17
|
+
import { useColorScheme } from '@/lib/useColorScheme';
|
|
21
18
|
import { NAV_THEME } from '@/theme';
|
|
22
19
|
|
|
23
20
|
export {
|
|
@@ -26,7 +23,6 @@ export {
|
|
|
26
23
|
} from 'expo-router';
|
|
27
24
|
|
|
28
25
|
export default function RootLayout() {
|
|
29
|
-
useInitialAndroidBarSync();
|
|
30
26
|
const { colorScheme, isDarkColorScheme } = useColorScheme();
|
|
31
27
|
|
|
32
28
|
return (
|
|
@@ -75,4 +71,4 @@ const MODAL_OPTIONS = {
|
|
|
75
71
|
animation: 'fade_from_bottom', // for android
|
|
76
72
|
title: 'Settings',
|
|
77
73
|
headerRight: () => <ThemeToggle />,
|
|
78
|
-
} as const;
|
|
74
|
+
} as const;
|
|
@@ -4,7 +4,7 @@ import { Platform } from 'react-native';
|
|
|
4
4
|
import { ScreenContent } from '@/components/ScreenContent';
|
|
5
5
|
|
|
6
6
|
<% if (props.internalizationPackage?.name === "i18next") { %>
|
|
7
|
-
import { InternalizationExample } from 'components/InternalizationExample';
|
|
7
|
+
import { InternalizationExample } from '../components/InternalizationExample';
|
|
8
8
|
<% } %>
|
|
9
9
|
|
|
10
10
|
export default function Modal() {
|
|
@@ -21,9 +21,11 @@ import { useMemo } from 'react';
|
|
|
21
21
|
import "react-native-gesture-handler";
|
|
22
22
|
|
|
23
23
|
<% if (props.analyticsPackage?.name === "vexo-analytics") { %>
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
const vexoApiKey = process.env.EXPO_PUBLIC_VEXO_API_KEY;
|
|
25
|
+
if (vexoApiKey) {
|
|
26
|
+
const { vexo } = require('vexo-analytics');
|
|
27
|
+
vexo(vexoApiKey); // eslint-disable-line
|
|
28
|
+
}
|
|
27
29
|
|
|
28
30
|
import Navigation from "./navigation"; // eslint-disable-line
|
|
29
31
|
<% } else { %>
|
|
@@ -3,7 +3,7 @@ import { StatusBar } from 'expo-status-bar';
|
|
|
3
3
|
import { Platform } from 'react-native';
|
|
4
4
|
|
|
5
5
|
<% if (props.internalizationPackage?.name === "i18next") { %>
|
|
6
|
-
import { InternalizationExample } from 'components/InternalizationExample';
|
|
6
|
+
import { InternalizationExample } from '../components/InternalizationExample';
|
|
7
7
|
<% } %>
|
|
8
8
|
|
|
9
9
|
export default function Modal() {
|
|
@@ -8,7 +8,7 @@ import { StyleSheet, View } from 'react-native';
|
|
|
8
8
|
<% } %>
|
|
9
9
|
|
|
10
10
|
<% if (props.internalizationPackage?.name === "i18next") { %>
|
|
11
|
-
import { InternalizationExample } from 'components/InternalizationExample';
|
|
11
|
+
import { InternalizationExample } from '../components/InternalizationExample';
|
|
12
12
|
<% } %>
|
|
13
13
|
|
|
14
14
|
import { Button } from '../components/Button';
|
package/build/types/types.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ export interface CliFlags {
|
|
|
7
7
|
eas: boolean;
|
|
8
8
|
publish: boolean;
|
|
9
9
|
}
|
|
10
|
-
export declare const availablePackages: readonly ["@react-navigation/drawer", "expo-router", "expoRouter", "firebase", "nativewind", "nativewindui", "nwui", "react-navigation", "reactNavigation", "react-native-gesture-handler", "react-native-
|
|
10
|
+
export declare const availablePackages: readonly ["@react-navigation/drawer", "expo-router", "expoRouter", "firebase", "nativewind", "nativewindui", "nwui", "react-navigation", "reactNavigation", "gesture-handler", "gestureHandler", "react-native-gesture-handler", "react-native-keyboard-controller", "react-native-screens", "react-native-svg", "keyboard-controller", "keyboardController", "reactnavigation", "screens", "stylesheet", "supabase", "svg", "unistyles", "i18next", "zustand", "vexo-analytics"];
|
|
11
11
|
export type AuthenticationSelect = 'supabase' | 'firebase' | undefined;
|
|
12
12
|
export type NavigationSelect = 'react-navigation' | 'expo-router' | undefined;
|
|
13
13
|
export type NavigationTypes = 'stack' | 'tabs' | 'drawer + tabs' | undefined;
|
|
@@ -16,10 +16,11 @@ export type PackageManager = 'yarn' | 'npm' | 'pnpm' | 'bun';
|
|
|
16
16
|
export type StateManagementSelect = 'zustand' | undefined;
|
|
17
17
|
export type Internalization = 'i18next';
|
|
18
18
|
export type Analytics = 'vexo-analytics';
|
|
19
|
+
export type SoftwareMansionSelect = 'react-native-gesture-handler' | 'react-native-keyboard-controller' | 'react-native-screens' | 'react-native-svg';
|
|
19
20
|
export type SelectedComponents = 'action-sheet' | 'activity-indicator' | 'activity-view' | 'avatar' | 'button' | 'date-picker' | 'picker' | 'progress-indicator' | 'ratings-indicator' | 'slider' | 'text' | 'toggle';
|
|
20
21
|
export type AvailablePackages = {
|
|
21
22
|
name: (typeof availablePackages)[number];
|
|
22
|
-
type: 'navigation' | 'styling' | 'authentication' | 'internationalization' | 'state-management' | 'analytics';
|
|
23
|
+
type: 'navigation' | 'styling' | 'authentication' | 'internationalization' | 'state-management' | 'analytics' | 'software-mansion';
|
|
23
24
|
options?: {
|
|
24
25
|
selectedComponents?: SelectedComponents[];
|
|
25
26
|
type?: NavigationTypes;
|
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
import { Toolbox } from 'gluegun/build/types/domain/toolbox';
|
|
2
2
|
import { AvailablePackages, CliResults, PackageManager } from '../types';
|
|
3
3
|
export declare function generateProjectFiles(authenticationPackage: AvailablePackages | undefined, analyticsPackage: AvailablePackages | undefined, cliResults: CliResults, files: string[], formattedFiles: any[], navigationPackage: AvailablePackages | undefined, packageManager: PackageManager, stylingPackage: AvailablePackages | undefined, toolbox: Toolbox, internalizationPackage: AvailablePackages | undefined, stateManagementPackage: AvailablePackages | undefined): any[];
|
|
4
|
+
export declare function toExpoSlug(projectName: string): string;
|
|
5
|
+
export declare function toExpoScheme(projectName: string): string;
|