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.
Files changed (59) hide show
  1. package/README.md +37 -23
  2. package/build/cli.js +5 -6
  3. package/build/commands/create-expo-stack.js +19 -7
  4. package/build/templates/base/.gitignore.ejs +1 -3
  5. package/build/templates/base/App.tsx.ejs +6 -4
  6. package/build/templates/base/app.json.ejs +18 -9
  7. package/build/templates/base/components/Container.tsx.ejs +2 -1
  8. package/build/templates/base/css-env.d.ts.ejs +1 -0
  9. package/build/templates/base/eslint.config.js.ejs +1 -2
  10. package/build/templates/base/package.json.ejs +49 -30
  11. package/build/templates/base/tsconfig.json.ejs +9 -4
  12. package/build/templates/packages/expo-router/drawer/app/_layout.tsx.ejs +5 -3
  13. package/build/templates/packages/expo-router/drawer/app/modal.tsx.ejs +1 -1
  14. package/build/templates/packages/expo-router/stack/app/_layout.tsx.ejs +5 -3
  15. package/build/templates/packages/expo-router/stack/app/index.tsx.ejs +1 -1
  16. package/build/templates/packages/expo-router/tabs/app/_layout.tsx.ejs +5 -3
  17. package/build/templates/packages/expo-router/tabs/app/modal.tsx.ejs +1 -1
  18. package/build/templates/packages/i18next/translation/index.ts.ejs +3 -3
  19. package/build/templates/packages/nativewindui/components/Container.tsx.ejs +2 -1
  20. package/build/templates/packages/nativewindui/components/TabBarIcon.tsx.ejs +2 -2
  21. package/build/templates/packages/nativewindui/components/nativewindui/Icon/Icon.ios.tsx.ejs +7 -4
  22. package/build/templates/packages/nativewindui/components/nativewindui/Icon/types.ts.ejs +4 -3
  23. package/build/templates/packages/nativewindui/drawer/app/(drawer)/index.tsx.ejs +7 -7
  24. package/build/templates/packages/nativewindui/drawer/app/_layout.tsx.ejs +4 -5
  25. package/build/templates/packages/nativewindui/drawer/app/modal.tsx.ejs +2 -2
  26. package/build/templates/packages/nativewindui/lib/useHeaderSearchBar.tsx.ejs +33 -0
  27. package/build/templates/packages/nativewindui/stack/app/_layout.tsx.ejs +1 -1
  28. package/build/templates/packages/nativewindui/stack/app/index.tsx.ejs +9 -39
  29. package/build/templates/packages/nativewindui/tabs/app/(tabs)/index.tsx.ejs +10 -13
  30. package/build/templates/packages/nativewindui/tabs/app/_layout.tsx.ejs +5 -9
  31. package/build/templates/packages/nativewindui/tabs/app/modal.tsx.ejs +1 -1
  32. package/build/templates/packages/nativewindui/theme/index.ts.ejs +1 -1
  33. package/build/templates/packages/react-navigation/App.tsx.ejs +5 -3
  34. package/build/templates/packages/react-navigation/screens/modal.tsx.ejs +1 -1
  35. package/build/templates/packages/react-navigation/screens/overview.tsx.ejs +1 -1
  36. package/build/types/types.d.ts +3 -2
  37. package/build/types/utilities/generateProjectFiles.d.ts +2 -0
  38. package/build/types/utilities/softwareMansion.d.ts +13 -0
  39. package/build/types/utilities/systemCommand.d.ts +3 -1
  40. package/build/types.js +10 -2
  41. package/build/utilities/clearNavigationPackages.js +2 -2
  42. package/build/utilities/clearStylingPackages.js +2 -2
  43. package/build/utilities/configAnalytics.js +2 -3
  44. package/build/utilities/configureProjectFiles.js +6 -4
  45. package/build/utilities/copyBaseAssets.js +2 -3
  46. package/build/utilities/generateNWUI.js +106 -3
  47. package/build/utilities/generateProjectFiles.js +25 -3
  48. package/build/utilities/getPackageManager.js +5 -6
  49. package/build/utilities/printOutput.js +54 -19
  50. package/build/utilities/renderTitle.js +2 -3
  51. package/build/utilities/runCLI.js +62 -3
  52. package/build/utilities/runEasConfigure.js +2 -3
  53. package/build/utilities/runIgnite.js +2 -3
  54. package/build/utilities/showHelp.js +8 -3
  55. package/build/utilities/softwareMansion.js +48 -0
  56. package/build/utilities/systemCommand.js +13 -5
  57. package/build/utilities/usePackage.js +2 -3
  58. package/build/utilities/validateProjectName.js +2 -3
  59. 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
- import { vexo } from 'vexo-analytics';
23
-
24
- vexo(process.env.EXPO_PUBLIC_VEXO_API_KEY);
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
- import { vexo } from 'vexo-analytics';
16
-
17
- vexo(process.env.EXPO_PUBLIC_VEXO_API_KEY);
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
- import { vexo } from 'vexo-analytics';
17
-
18
- vexo(process.env.EXPO_PUBLIC_VEXO_API_KEY);
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 'translation/en.json';
3
- import fr from 'translation/fr.json';
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, SafeAreaView } from 'react-native';
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: string;
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
- name={name ?? 'questionmark'}
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 = SymbolViewProps['style'] &
10
+ type Style = SymbolIconProps['style'] &
10
11
  MaterialIconsProps['style'] &
11
12
  MaterialCommunityIconsProps['style'];
12
13
 
13
- type IconProps = IconMapper<SymbolViewProps, MaterialIconsProps, MaterialCommunityIconsProps> & {
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 '@react-navigation/elements';
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="file-plus-outline" size={42} color={colors.grey} />
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
- onChange={(ev) => {
230
- setDate(new Date(ev.nativeEvent.timestamp));
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 '@react-navigation/native';
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, useInitialAndroidBarSync } from '@/lib/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="file-plus-outline" size={42} color={colors.grey} />
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 '@react-navigation/native';
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 '@react-navigation/elements';
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
- if (id) clearInterval(id);
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
- onChange={(ev) => {
382
- setDate(new Date(ev.nativeEvent.timestamp));
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 '@react-navigation/elements';
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="file-plus-outline" size={42} color={colors.grey} />
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
- onChange={(ev) => {
231
- setDate(new Date(ev.nativeEvent.timestamp));
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
- if (!id) {
269
- id = setInterval(() => {
270
- setProgress((prev) => (prev >= 99 ? 0 : prev + 5));
271
- }, 1000);
272
- }
266
+ const intervalId = setInterval(() => {
267
+ setProgress((prev) => (prev >= 99 ? 0 : prev + 5));
268
+ }, 1000);
269
+
273
270
  return () => {
274
- if (id) clearInterval(id);
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 '@react-navigation/native';
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 { Link, Stack } from 'expo-router';
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 { cn } from '@/lib/cn';
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() {
@@ -1,4 +1,4 @@
1
- import { Theme, DefaultTheme, DarkTheme } from '@react-navigation/native';
1
+ import { Theme, DefaultTheme, DarkTheme } from 'expo-router/react-navigation';
2
2
 
3
3
  import { COLORS } from './colors';
4
4
 
@@ -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
- import { vexo } from 'vexo-analytics';
25
-
26
- vexo(process.env.VEXO_API_KEY); // eslint-disable-line
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';
@@ -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-reanimated", "reactnavigation", "stylesheet", "supabase", "unistyles", "i18next", "zustand", "vexo-analytics"];
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;