create-expo-stack 2.6.5 → 2.7.0-next.ba3b85d
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 +7 -0
- package/build/templates/base/App.tsx.ejs +3 -0
- package/build/templates/base/babel.config.js.ejs +1 -1
- package/build/templates/base/package.json.ejs +14 -3
- package/build/templates/base/prettier.config.js.ejs +1 -1
- package/build/templates/base/tsconfig.json.ejs +10 -6
- package/build/templates/packages/expo-router/drawer/app/_layout.tsx.ejs +4 -1
- package/build/templates/packages/expo-router/stack/app/_layout.tsx.ejs +4 -1
- package/build/templates/packages/expo-router/tabs/app/_layout.tsx.ejs +4 -1
- package/build/templates/packages/nativewindui/app/+not-found.tsx.ejs +18 -0
- package/build/templates/packages/nativewindui/app/_layout.tsx.ejs +85 -0
- package/build/templates/packages/nativewindui/app/bottom-tabs/_layout.tsx.ejs +34 -0
- package/build/templates/packages/nativewindui/app/bottom-tabs/index.tsx.ejs +11 -0
- package/build/templates/packages/nativewindui/app/bottom-tabs/profile.tsx.ejs +11 -0
- package/build/templates/packages/nativewindui/app/drawer/_layout.tsx.ejs +29 -0
- package/build/templates/packages/nativewindui/app/drawer/index.tsx.ejs +11 -0
- package/build/templates/packages/nativewindui/app/index.tsx.ejs +165 -0
- package/build/templates/packages/nativewindui/app/modal.tsx.ejs +32 -0
- package/build/templates/packages/nativewindui/app/top-tabs/_layout.tsx.ejs +71 -0
- package/build/templates/packages/nativewindui/app/top-tabs/following.tsx.ejs +13 -0
- package/build/templates/packages/nativewindui/app/top-tabs/index.tsx.ejs +13 -0
- package/build/templates/packages/nativewindui/app/top-tabs/my-group.tsx.ejs +13 -0
- package/build/templates/packages/nativewindui/components/Text.tsx.ejs +55 -0
- package/build/templates/packages/nativewindui/components/ThemeToggle.tsx.ejs +39 -0
- package/build/templates/packages/nativewindui/components/Toggle.tsx.ejs +17 -0
- package/build/templates/packages/nativewindui/expo-env.d.ts.ejs +3 -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 +14 -0
- package/build/templates/packages/nativewindui/lib/useHeaderSearchBar.tsx.ejs +31 -0
- package/build/templates/packages/nativewindui/metro.config.js.ejs +10 -0
- package/build/templates/packages/nativewindui/nativewind-env.d.ts.ejs +1 -0
- package/build/templates/packages/nativewindui/tailwind.config.js.ejs +66 -0
- package/build/templates/packages/nativewindui/theme/colors.ts.ejs +71 -0
- package/build/templates/packages/nativewindui/theme/index.ts.ejs +29 -0
- package/build/templates/packages/react-navigation/App.tsx.ejs +4 -1
- package/build/types/types.d.ts +2 -2
- package/build/types.js +2 -1
- package/build/utilities/configureProjectFiles.js +239 -200
- package/build/utilities/generateProjectFiles.js +18 -13
- package/build/utilities/printOutput.js +5 -5
- package/build/utilities/runCLI.js +45 -22
- package/package.json +67 -67
package/README.md
CHANGED
|
@@ -279,6 +279,13 @@ Thanks go to these wonderful people:
|
|
|
279
279
|
<sub><b>Sean Boult</b></sub>
|
|
280
280
|
</a>
|
|
281
281
|
</td>
|
|
282
|
+
<td align="center">
|
|
283
|
+
<a href="https://github.com/YounessHassoune">
|
|
284
|
+
<img src="https://avatars.githubusercontent.com/u/36106440?v=4" width="100;" alt="YounessHassoune"/>
|
|
285
|
+
<br />
|
|
286
|
+
<sub><b>YOUNESS HASSOUNE</b></sub>
|
|
287
|
+
</a>
|
|
288
|
+
</td>
|
|
282
289
|
<td align="center">
|
|
283
290
|
<a href="https://github.com/bautistaaa">
|
|
284
291
|
<img src="https://avatars.githubusercontent.com/u/3660667?v=4" width="100;" alt="bautistaaa"/>
|
|
@@ -8,6 +8,9 @@ import { StatusBar } from 'expo-status-bar';
|
|
|
8
8
|
|
|
9
9
|
<% if (props.stylingPackage?.name === "nativewind") { %>
|
|
10
10
|
import './global.css';
|
|
11
|
+
<% } else if (props.stylingPackage?.name === "nativewinui") { %>
|
|
12
|
+
import './global.css';
|
|
13
|
+
import 'expo-dev-client';
|
|
11
14
|
<% } else if (props.stylingPackage?.name === "restyle") { %>
|
|
12
15
|
import { ThemeProvider } from '@shopify/restyle';
|
|
13
16
|
import { theme } from 'theme';
|
|
@@ -17,7 +17,7 @@ module.exports = function(api) {
|
|
|
17
17
|
<% } %>
|
|
18
18
|
|
|
19
19
|
return {
|
|
20
|
-
<% if (props.stylingPackage?.name === "nativewind") { %>
|
|
20
|
+
<% if (props.stylingPackage?.name === "nativewind" || props.stylingPackage?.name === "nativewindui") { %>
|
|
21
21
|
presets: [
|
|
22
22
|
['babel-preset-expo', { jsxImportSource: 'nativewind' }],
|
|
23
23
|
'nativewind/babel',
|
|
@@ -16,9 +16,20 @@
|
|
|
16
16
|
"web": "expo start --web"
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
|
-
<% if (props.stylingPackage?.name === "nativewind") { %>
|
|
19
|
+
<% if (props.stylingPackage?.name === "nativewind" || props.stylingPackage?.name === "nativewindui") { %>
|
|
20
20
|
"nativewind": "^4.0.1",
|
|
21
21
|
<% } %>
|
|
22
|
+
<% if (props.stylingPackage?.name === "nativewindui") { %>
|
|
23
|
+
"@react-navigation/material-top-tabs": "^6.6.13",
|
|
24
|
+
"@roninoss/icons": "^0.0.3",
|
|
25
|
+
"class-variance-authority": "^0.7.0",
|
|
26
|
+
"clsx": "^2.1.0",
|
|
27
|
+
"expo-dev-client": "~3.3.8",
|
|
28
|
+
"tailwind-merge": "^2.2.1",
|
|
29
|
+
"react-native-uitextview": "^1.1.4",
|
|
30
|
+
"react-native-pager-view": "6.2.3",
|
|
31
|
+
"react-native-tab-view": "^3.5.2",
|
|
32
|
+
<% } %>
|
|
22
33
|
|
|
23
34
|
<% if (props.stylingPackage?.name === "restyle") { %>
|
|
24
35
|
"@shopify/restyle": "^2.4.2",
|
|
@@ -112,7 +123,7 @@
|
|
|
112
123
|
"eslint": "^8.50.0",
|
|
113
124
|
"eslint-config-universe": "^12.0.0",
|
|
114
125
|
"prettier": "^3.2.5",
|
|
115
|
-
<% if (props.stylingPackage?.name === "nativewind") { %>
|
|
126
|
+
<% if (props.stylingPackage?.name === "nativewind" || props.stylingPackage?.name === "nativewindui") { %>
|
|
116
127
|
"tailwindcss": "^3.4.0",
|
|
117
128
|
"prettier-plugin-tailwindcss": "^0.5.11",
|
|
118
129
|
<% } %>
|
|
@@ -124,7 +135,7 @@
|
|
|
124
135
|
"eslintConfig": {
|
|
125
136
|
"extends": "universe/native"
|
|
126
137
|
},
|
|
127
|
-
<% if (props.navigationPackage?.name ===
|
|
138
|
+
<% if (props.navigationPackage?.name === "expo-router") { %>
|
|
128
139
|
"resolutions": {
|
|
129
140
|
"expo-modules-core": "~1.11.0"
|
|
130
141
|
},
|
|
@@ -4,7 +4,7 @@ module.exports = {
|
|
|
4
4
|
singleQuote: true,
|
|
5
5
|
bracketSameLine: true,
|
|
6
6
|
trailingComma: 'es5',
|
|
7
|
-
<% if (props.stylingPackage?.name === "nativewind") { %>
|
|
7
|
+
<% if (props.stylingPackage?.name === "nativewind" || props.stylingPackage?.name === "nativewindui") { %>
|
|
8
8
|
plugins: [require.resolve("prettier-plugin-tailwindcss")],
|
|
9
9
|
tailwindAttributes: ["className"],
|
|
10
10
|
<% } %>
|
|
@@ -6,12 +6,16 @@
|
|
|
6
6
|
,
|
|
7
7
|
"baseUrl": ".",
|
|
8
8
|
"paths": {
|
|
9
|
-
<% if
|
|
10
|
-
|
|
11
|
-
<% } else
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
9
|
+
<% if (props.stylingPackage?.name === 'nativewindui') { %>
|
|
10
|
+
"@/*": [ "./*" ]
|
|
11
|
+
<% } else { %>
|
|
12
|
+
<% if (props.navigationPackage?.name === "expo-router" && props.flags.importAlias === true) { %>
|
|
13
|
+
"~/*": ["*"]
|
|
14
|
+
<% } else if (props.flags.importAlias === true) { %>
|
|
15
|
+
"~/*": ["src/*"]
|
|
16
|
+
<% } else { %>
|
|
17
|
+
"<%= props.flags.importAlias %>": ["src/*"]
|
|
18
|
+
<% } %>
|
|
15
19
|
<% } %>
|
|
16
20
|
}
|
|
17
21
|
<% } %>
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
<% if (props.stylingPackage?.name === "nativewind") { %>
|
|
2
|
-
import '
|
|
2
|
+
import './global.css';
|
|
3
|
+
<% } else if (props.stylingPackage?.name === "nativewinui") { %>
|
|
4
|
+
import './global.css';
|
|
5
|
+
import 'expo-dev-client';
|
|
3
6
|
<% } %>
|
|
4
7
|
<% if (props.stylingPackage?.name === "unistyles") { %>
|
|
5
8
|
import '../unistyles';
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
<% if (props.stylingPackage?.name === "nativewind") { %>
|
|
2
|
-
import '
|
|
2
|
+
import './global.css';
|
|
3
|
+
<% } else if (props.stylingPackage?.name === "nativewinui") { %>
|
|
4
|
+
import './global.css';
|
|
5
|
+
import 'expo-dev-client';
|
|
3
6
|
<% } %>
|
|
4
7
|
<% if (props.stylingPackage?.name === "unistyles") { %>
|
|
5
8
|
import '../unistyles';
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
<% if (props.stylingPackage?.name === "nativewind") { %>
|
|
2
|
-
import '
|
|
2
|
+
import './global.css';
|
|
3
|
+
<% } else if (props.stylingPackage?.name === "nativewinui") { %>
|
|
4
|
+
import './global.css';
|
|
5
|
+
import 'expo-dev-client';
|
|
3
6
|
<% } %>
|
|
4
7
|
<% if (props.stylingPackage?.name === "unistyles") { %>
|
|
5
8
|
import '../unistyles';
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Link, Stack } from 'expo-router';
|
|
2
|
+
import { View } from 'react-native';
|
|
3
|
+
import { Text } from '@/components/Text';
|
|
4
|
+
|
|
5
|
+
export default function NotFoundScreen() {
|
|
6
|
+
return (
|
|
7
|
+
<>
|
|
8
|
+
<Stack.Screen options={{ title: 'Oops!' }} />
|
|
9
|
+
<View className='flex-1 items-center justify-center p-5 bg-background'>
|
|
10
|
+
<Text variant='largeTitle'>This screen doesn't exist.</Text>
|
|
11
|
+
|
|
12
|
+
<Link href='/' className='m-4 py-4'>
|
|
13
|
+
<Text>Go to home screen!</Text>
|
|
14
|
+
</Link>
|
|
15
|
+
</View>
|
|
16
|
+
</>
|
|
17
|
+
);
|
|
18
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import '@/global.css';
|
|
2
|
+
import 'expo-dev-client';
|
|
3
|
+
import { ThemeProvider as NavThemeProvider } from '@react-navigation/native';
|
|
4
|
+
import { Icon } from '@roninoss/icons';
|
|
5
|
+
import { Link, Stack } from 'expo-router';
|
|
6
|
+
import { StatusBar } from 'expo-status-bar';
|
|
7
|
+
import { Pressable, View } from 'react-native';
|
|
8
|
+
import { GestureHandlerRootView } from 'react-native-gesture-handler';
|
|
9
|
+
|
|
10
|
+
import { ThemeToggle } from '@/components/ThemeToggle';
|
|
11
|
+
import { cn } from '@/lib/cn';
|
|
12
|
+
import { useColorScheme } from '@/lib/useColorScheme';
|
|
13
|
+
import { NAV_THEME } from '@/theme';
|
|
14
|
+
|
|
15
|
+
export {
|
|
16
|
+
// Catch any errors thrown by the Layout component.
|
|
17
|
+
ErrorBoundary,
|
|
18
|
+
} from 'expo-router';
|
|
19
|
+
|
|
20
|
+
export default function RootLayout() {
|
|
21
|
+
const { colorScheme, isDarkColorScheme } = useColorScheme();
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<>
|
|
25
|
+
<StatusBar
|
|
26
|
+
key={`root-status-bar-${isDarkColorScheme ? 'light' : 'dark'}`}
|
|
27
|
+
style={isDarkColorScheme ? 'light' : 'dark'}
|
|
28
|
+
/>
|
|
29
|
+
<GestureHandlerRootView style={{ flex: 1 }}>
|
|
30
|
+
<NavThemeProvider value={NAV_THEME[colorScheme]}>
|
|
31
|
+
<Stack screenOptions={SCREEN_OPTIONS}>
|
|
32
|
+
<Stack.Screen name="index" options={INDEX_OPTIONS} />
|
|
33
|
+
<Stack.Screen name="top-tabs" options={TOP_TABS_OPTIONS} />
|
|
34
|
+
<Stack.Screen name="drawer" options={DEFAULT_OPTIONS} />
|
|
35
|
+
<Stack.Screen name="bottom-tabs" options={DEFAULT_OPTIONS} />
|
|
36
|
+
<Stack.Screen name="modal" options={MODAL_OPTIONS} />
|
|
37
|
+
</Stack>
|
|
38
|
+
</NavThemeProvider>
|
|
39
|
+
</GestureHandlerRootView>
|
|
40
|
+
</>
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const SCREEN_OPTIONS = {
|
|
45
|
+
animation: 'ios', // for android
|
|
46
|
+
} as const;
|
|
47
|
+
|
|
48
|
+
const INDEX_OPTIONS = {
|
|
49
|
+
headerLargeTitle: true,
|
|
50
|
+
title: 'NativeWindUI',
|
|
51
|
+
headerRight: () => <SettingsIcon />,
|
|
52
|
+
} as const;
|
|
53
|
+
|
|
54
|
+
function SettingsIcon() {
|
|
55
|
+
const { colors } = useColorScheme();
|
|
56
|
+
return (
|
|
57
|
+
<Link href="/modal" asChild>
|
|
58
|
+
<Pressable className="opacity-80">
|
|
59
|
+
{({ pressed }) => (
|
|
60
|
+
<View className={cn(pressed ? 'opacity-50' : 'opacity-90')}>
|
|
61
|
+
<Icon name="cog-outline" color={colors.foreground} />
|
|
62
|
+
</View>
|
|
63
|
+
)}
|
|
64
|
+
</Pressable>
|
|
65
|
+
</Link>
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const TOP_TABS_OPTIONS = {
|
|
70
|
+
title: 'Top Tabs',
|
|
71
|
+
headerShadowVisible: false,
|
|
72
|
+
headerBackTitle: 'Back',
|
|
73
|
+
headerRight: () => <ThemeToggle />,
|
|
74
|
+
} as const;
|
|
75
|
+
|
|
76
|
+
const MODAL_OPTIONS = {
|
|
77
|
+
presentation: 'modal',
|
|
78
|
+
animation: 'fade_from_bottom', // for android
|
|
79
|
+
title: 'Settings',
|
|
80
|
+
headerRight: () => <ThemeToggle />,
|
|
81
|
+
} as const;
|
|
82
|
+
|
|
83
|
+
const DEFAULT_OPTIONS = {
|
|
84
|
+
headerShown: false,
|
|
85
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { ThemeToggle } from '@/components/ThemeToggle';
|
|
2
|
+
import { Icon } from '@roninoss/icons';
|
|
3
|
+
import { Tabs } from 'expo-router';
|
|
4
|
+
import { View } from 'react-native';
|
|
5
|
+
|
|
6
|
+
export default function TabsLayout() {
|
|
7
|
+
return (
|
|
8
|
+
<Tabs screenOptions={SCREEN_OPTIONS}>
|
|
9
|
+
<Tabs.Screen name='index' options={INDEX_OPTIONS} />
|
|
10
|
+
<Tabs.Screen name='profile' options={PROFILE_OPTIONS} />
|
|
11
|
+
</Tabs>
|
|
12
|
+
);
|
|
13
|
+
}
|
|
14
|
+
const SCREEN_OPTIONS = {
|
|
15
|
+
headerRight: () => (
|
|
16
|
+
<View className='px-4'>
|
|
17
|
+
<ThemeToggle />
|
|
18
|
+
</View>
|
|
19
|
+
),
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const INDEX_OPTIONS = {
|
|
23
|
+
title: 'Home',
|
|
24
|
+
tabBarIcon({ color, size }: { color: string; size: number }) {
|
|
25
|
+
return <Icon name='home' color={color} size={size} />;
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const PROFILE_OPTIONS = {
|
|
30
|
+
title: 'Profile',
|
|
31
|
+
tabBarIcon({ color, size }: { color: string; size: number }) {
|
|
32
|
+
return <Icon name='person' color={color} size={size} />;
|
|
33
|
+
},
|
|
34
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { router } from 'expo-router';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { Button, View } from 'react-native';
|
|
4
|
+
|
|
5
|
+
export default function HomeScreen() {
|
|
6
|
+
return (
|
|
7
|
+
<View className='flex-1 justify-center items-center'>
|
|
8
|
+
<Button title='Go back' onPress={router.back} />
|
|
9
|
+
</View>
|
|
10
|
+
);
|
|
11
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { router } from 'expo-router';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { Button, View } from 'react-native';
|
|
4
|
+
|
|
5
|
+
export default function ProfileScreen() {
|
|
6
|
+
return (
|
|
7
|
+
<View className='flex-1 justify-center items-center'>
|
|
8
|
+
<Button color={'orange'} title='Go to home tab' onPress={router.back} />
|
|
9
|
+
</View>
|
|
10
|
+
);
|
|
11
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { ThemeToggle } from '@/components/ThemeToggle';
|
|
2
|
+
import { useColorScheme } from '@/lib/useColorScheme';
|
|
3
|
+
import { Drawer } from 'expo-router/drawer';
|
|
4
|
+
import { View } from 'react-native';
|
|
5
|
+
|
|
6
|
+
export default function DrawerLayout() {
|
|
7
|
+
const { colors } = useColorScheme();
|
|
8
|
+
return (
|
|
9
|
+
<Drawer
|
|
10
|
+
screenOptions={{
|
|
11
|
+
headerTintColor: colors.foreground,
|
|
12
|
+
headerRight,
|
|
13
|
+
}}
|
|
14
|
+
>
|
|
15
|
+
<Drawer.Screen name='index' options={EXPLORE_OPTIONS} />
|
|
16
|
+
</Drawer>
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function headerRight() {
|
|
21
|
+
return (
|
|
22
|
+
<View className='px-4'>
|
|
23
|
+
<ThemeToggle />
|
|
24
|
+
</View>
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
const EXPLORE_OPTIONS = {
|
|
28
|
+
title: 'Explore',
|
|
29
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { router } from 'expo-router';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { Button, View } from 'react-native';
|
|
4
|
+
|
|
5
|
+
export default function ExploreScreen() {
|
|
6
|
+
return (
|
|
7
|
+
<View className='flex-1 justify-center items-center'>
|
|
8
|
+
<Button title='Go back' onPress={router.back} />
|
|
9
|
+
</View>
|
|
10
|
+
);
|
|
11
|
+
}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { Icon } from '@roninoss/icons';
|
|
2
|
+
import { Link } from 'expo-router';
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { FlatList, Pressable, View } from 'react-native';
|
|
5
|
+
|
|
6
|
+
import { Text } from '@/components/Text';
|
|
7
|
+
import { Toggle } from '@/components/Toggle';
|
|
8
|
+
import { cn } from '@/lib/cn';
|
|
9
|
+
import { useColorScheme } from '@/lib/useColorScheme';
|
|
10
|
+
import { useHeaderSearchBar } from '@/lib/useHeaderSearchBar';
|
|
11
|
+
|
|
12
|
+
export default function Screen() {
|
|
13
|
+
const { colors } = useColorScheme();
|
|
14
|
+
const searchValue = useHeaderSearchBar();
|
|
15
|
+
|
|
16
|
+
const data = searchValue
|
|
17
|
+
? COMPONENTS.filter((c) => c.name.toLowerCase().includes(searchValue.toLowerCase()))
|
|
18
|
+
: COMPONENTS;
|
|
19
|
+
|
|
20
|
+
const screens = searchValue
|
|
21
|
+
? FULL_SCREEN_COMPONENTS.filter((c) => c.name.toLowerCase().includes(searchValue.toLowerCase()))
|
|
22
|
+
: FULL_SCREEN_COMPONENTS;
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<FlatList
|
|
26
|
+
contentInsetAdjustmentBehavior="automatic"
|
|
27
|
+
data={data}
|
|
28
|
+
contentContainerClassName="py-4"
|
|
29
|
+
extraData={searchValue}
|
|
30
|
+
removeClippedSubviews={false} // used for selecting text on android
|
|
31
|
+
keyExtractor={(item) => item.name}
|
|
32
|
+
ItemSeparatorComponent={() => <View className="p-2" />}
|
|
33
|
+
renderItem={({ item }) => {
|
|
34
|
+
return (
|
|
35
|
+
<Card title={item.name}>
|
|
36
|
+
<item.component />
|
|
37
|
+
</Card>
|
|
38
|
+
);
|
|
39
|
+
}}
|
|
40
|
+
ListFooterComponent={() => {
|
|
41
|
+
return (
|
|
42
|
+
<FlatList
|
|
43
|
+
ListHeaderComponent={() => (
|
|
44
|
+
<View className={cn('px-4 pb-2 pt-6', screens.length === 0 && 'hidden')}>
|
|
45
|
+
<Text className="text-xs font-semibold opacity-50 ">NAVIGATORS</Text>
|
|
46
|
+
</View>
|
|
47
|
+
)}
|
|
48
|
+
scrollToOverflowEnabled
|
|
49
|
+
scrollEnabled={false}
|
|
50
|
+
contentInsetAdjustmentBehavior="automatic"
|
|
51
|
+
data={screens}
|
|
52
|
+
className="ios:px-4"
|
|
53
|
+
extraData={searchValue}
|
|
54
|
+
keyExtractor={(item) => item.name}
|
|
55
|
+
renderItem={({ index, item }) => {
|
|
56
|
+
const isLast = index === screens.length - 1;
|
|
57
|
+
return (
|
|
58
|
+
<Link href={item.href} asChild>
|
|
59
|
+
<Pressable
|
|
60
|
+
className={cn(
|
|
61
|
+
index === 0 && 'ios:rounded-t-xl border-t',
|
|
62
|
+
isLast && 'ios:rounded-b-xl border-b',
|
|
63
|
+
'bg-card ios:border-l ios:border-r border-border flex-row active:opacity-80'
|
|
64
|
+
)}>
|
|
65
|
+
<View
|
|
66
|
+
className={cn(
|
|
67
|
+
!isLast && 'border-border border-b',
|
|
68
|
+
'flex-1 flex-row items-center justify-between px-4 py-3'
|
|
69
|
+
)}>
|
|
70
|
+
<Text>{item.name}</Text>
|
|
71
|
+
<Icon name="chevron-right" size={18} color={colors.grey} />
|
|
72
|
+
</View>
|
|
73
|
+
</Pressable>
|
|
74
|
+
</Link>
|
|
75
|
+
);
|
|
76
|
+
}}
|
|
77
|
+
/>
|
|
78
|
+
);
|
|
79
|
+
}}
|
|
80
|
+
/>
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function Card({ children, title }: { children: React.ReactNode; title: string }) {
|
|
85
|
+
return (
|
|
86
|
+
<View className="px-4">
|
|
87
|
+
<View className="bg-card border-border gap-4 rounded-xl border p-4 pb-6 shadow-sm shadow-black/10 dark:shadow-none">
|
|
88
|
+
<Text className="text-center text-sm font-medium tracking-wider opacity-60">{title}</Text>
|
|
89
|
+
{children}
|
|
90
|
+
</View>
|
|
91
|
+
</View>
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function ToggleExample() {
|
|
96
|
+
const [switchValue, setSwitchValue] = React.useState(true);
|
|
97
|
+
return (
|
|
98
|
+
<View className="items-center">
|
|
99
|
+
<Toggle value={switchValue} onValueChange={setSwitchValue} />
|
|
100
|
+
</View>
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const COMPONENTS = [
|
|
105
|
+
{
|
|
106
|
+
name: 'Toggle',
|
|
107
|
+
component: ToggleExample,
|
|
108
|
+
},
|
|
109
|
+
|
|
110
|
+
{
|
|
111
|
+
name: 'Text',
|
|
112
|
+
component: () => (
|
|
113
|
+
<View className="gap-2">
|
|
114
|
+
<Text variant="largeTitle" className="text-center">
|
|
115
|
+
Large Title
|
|
116
|
+
</Text>
|
|
117
|
+
<Text variant="title1" className="text-center">
|
|
118
|
+
Title 1
|
|
119
|
+
</Text>
|
|
120
|
+
<Text variant="title2" className="text-center">
|
|
121
|
+
Title 2
|
|
122
|
+
</Text>
|
|
123
|
+
<Text variant="title3" className="text-center">
|
|
124
|
+
Title 3
|
|
125
|
+
</Text>
|
|
126
|
+
<Text variant="heading" className="text-center">
|
|
127
|
+
Heading
|
|
128
|
+
</Text>
|
|
129
|
+
<Text variant="body" className="text-center">
|
|
130
|
+
Body
|
|
131
|
+
</Text>
|
|
132
|
+
<Text variant="callout" className="text-center">
|
|
133
|
+
Callout
|
|
134
|
+
</Text>
|
|
135
|
+
<Text variant="subhead" className="text-center">
|
|
136
|
+
Subhead
|
|
137
|
+
</Text>
|
|
138
|
+
<Text variant="footnote" className="text-center">
|
|
139
|
+
Footnote
|
|
140
|
+
</Text>
|
|
141
|
+
<Text variant="caption1" className="text-center">
|
|
142
|
+
Caption 1
|
|
143
|
+
</Text>
|
|
144
|
+
<Text variant="caption2" className="text-center">
|
|
145
|
+
Caption 2
|
|
146
|
+
</Text>
|
|
147
|
+
</View>
|
|
148
|
+
),
|
|
149
|
+
},
|
|
150
|
+
] as const;
|
|
151
|
+
|
|
152
|
+
const FULL_SCREEN_COMPONENTS = [
|
|
153
|
+
{
|
|
154
|
+
name: 'Drawer Navigation',
|
|
155
|
+
href: '/drawer/',
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
name: 'Bottom Tabs Navigation',
|
|
159
|
+
href: '/bottom-tabs/',
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
name: 'Top Tabs Navigation',
|
|
163
|
+
href: '/top-tabs/',
|
|
164
|
+
},
|
|
165
|
+
] as const;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Text } from '@/components/Text';
|
|
2
|
+
import { Link } from 'expo-router';
|
|
3
|
+
import { StatusBar } from 'expo-status-bar';
|
|
4
|
+
import { useColorScheme } from 'nativewind';
|
|
5
|
+
import { Platform, View } from 'react-native';
|
|
6
|
+
|
|
7
|
+
export default function ModalScreen() {
|
|
8
|
+
const { colorScheme } = useColorScheme();
|
|
9
|
+
return (
|
|
10
|
+
<>
|
|
11
|
+
<StatusBar
|
|
12
|
+
style={
|
|
13
|
+
Platform.OS === 'ios'
|
|
14
|
+
? 'light'
|
|
15
|
+
: colorScheme === 'dark'
|
|
16
|
+
? 'light'
|
|
17
|
+
: 'dark'
|
|
18
|
+
}
|
|
19
|
+
/>
|
|
20
|
+
<View className='flex-1 justify-center items-center gap-8 pb-12'>
|
|
21
|
+
<View className='items-center gap-2'>
|
|
22
|
+
<Text variant='largeTitle' className='font-bold'>
|
|
23
|
+
NativeWindUI
|
|
24
|
+
</Text>
|
|
25
|
+
<Link href={'https://nativewindui.com/'}>
|
|
26
|
+
<Text className='text-primary'>https://nativewindui.com/</Text>
|
|
27
|
+
</Link>
|
|
28
|
+
</View>
|
|
29
|
+
</View>
|
|
30
|
+
</>
|
|
31
|
+
);
|
|
32
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { useColorScheme } from '@/lib/useColorScheme';
|
|
2
|
+
import type {
|
|
3
|
+
MaterialTopTabNavigationEventMap,
|
|
4
|
+
MaterialTopTabNavigationOptions,
|
|
5
|
+
} from '@react-navigation/material-top-tabs';
|
|
6
|
+
import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs';
|
|
7
|
+
import {
|
|
8
|
+
type ParamListBase,
|
|
9
|
+
type TabNavigationState,
|
|
10
|
+
} from '@react-navigation/native';
|
|
11
|
+
import { withLayoutContext } from 'expo-router';
|
|
12
|
+
import { Dimensions } from 'react-native';
|
|
13
|
+
|
|
14
|
+
const { width } = Dimensions.get('screen');
|
|
15
|
+
|
|
16
|
+
const { Navigator } = createMaterialTopTabNavigator();
|
|
17
|
+
|
|
18
|
+
const TopTabs = withLayoutContext<
|
|
19
|
+
MaterialTopTabNavigationOptions,
|
|
20
|
+
typeof Navigator,
|
|
21
|
+
TabNavigationState<ParamListBase>,
|
|
22
|
+
MaterialTopTabNavigationEventMap
|
|
23
|
+
>(Navigator);
|
|
24
|
+
|
|
25
|
+
const SCREENS = [
|
|
26
|
+
{
|
|
27
|
+
name: 'index',
|
|
28
|
+
title: 'For You',
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
name: 'following',
|
|
32
|
+
title: 'Following',
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
name: 'my-group',
|
|
36
|
+
title: 'My Group',
|
|
37
|
+
},
|
|
38
|
+
];
|
|
39
|
+
|
|
40
|
+
export default function TopTabsLayout() {
|
|
41
|
+
const { colors } = useColorScheme();
|
|
42
|
+
return (
|
|
43
|
+
<TopTabs
|
|
44
|
+
initialRouteName='index'
|
|
45
|
+
screenOptions={{
|
|
46
|
+
tabBarActiveTintColor: colors.blue,
|
|
47
|
+
tabBarInactiveTintColor: 'grey',
|
|
48
|
+
tabBarLabelStyle: {
|
|
49
|
+
fontSize: 14,
|
|
50
|
+
textTransform: 'capitalize',
|
|
51
|
+
fontWeight: 'bold',
|
|
52
|
+
},
|
|
53
|
+
tabBarIndicatorStyle: {
|
|
54
|
+
backgroundColor: colors.blue,
|
|
55
|
+
},
|
|
56
|
+
tabBarScrollEnabled: true,
|
|
57
|
+
tabBarItemStyle: { width: width / SCREENS.length },
|
|
58
|
+
}}
|
|
59
|
+
>
|
|
60
|
+
{SCREENS.map(({ name, title }) => (
|
|
61
|
+
<TopTabs.Screen
|
|
62
|
+
key={name}
|
|
63
|
+
name={name}
|
|
64
|
+
options={{
|
|
65
|
+
title,
|
|
66
|
+
}}
|
|
67
|
+
/>
|
|
68
|
+
))}
|
|
69
|
+
</TopTabs>
|
|
70
|
+
);
|
|
71
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Text } from '@/components/Text';
|
|
2
|
+
import { View } from 'react-native';
|
|
3
|
+
|
|
4
|
+
export default function FollowingScreen() {
|
|
5
|
+
return (
|
|
6
|
+
<View className='flex-1 justify-center items-center gap-5'>
|
|
7
|
+
<View className='items-center gap-1'>
|
|
8
|
+
<Text variant='title1'>Following Tab</Text>
|
|
9
|
+
<Text>Swipe to see other tabs</Text>
|
|
10
|
+
</View>
|
|
11
|
+
</View>
|
|
12
|
+
);
|
|
13
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Text } from '@/components/Text';
|
|
2
|
+
import { View } from 'react-native';
|
|
3
|
+
|
|
4
|
+
export default function ForYouScreen() {
|
|
5
|
+
return (
|
|
6
|
+
<View className='flex-1 justify-center items-center gap-5'>
|
|
7
|
+
<View className='items-center gap-1'>
|
|
8
|
+
<Text variant='title1'>For You Tab</Text>
|
|
9
|
+
<Text>Swipe to see other tabs</Text>
|
|
10
|
+
</View>
|
|
11
|
+
</View>
|
|
12
|
+
);
|
|
13
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { View } from 'react-native';
|
|
2
|
+
import { Text } from '@/components/Text';
|
|
3
|
+
|
|
4
|
+
export default function MyGroupScreen() {
|
|
5
|
+
return (
|
|
6
|
+
<View className='flex-1 justify-center items-center gap-5'>
|
|
7
|
+
<View className='items-center gap-1'>
|
|
8
|
+
<Text variant='title1'>My Group Tab</Text>
|
|
9
|
+
<Text>Swipe to see other tabs</Text>
|
|
10
|
+
</View>
|
|
11
|
+
</View>
|
|
12
|
+
);
|
|
13
|
+
}
|