feat: add a simple stack and material tabs integration (#39)

This commit is contained in:
Satyajit Sahoo
2019-08-03 20:05:10 +02:00
committed by Michał Osadnik
parent ce7d163073
commit e0bee10e6b
11 changed files with 234 additions and 184 deletions

View File

@@ -1 +1,3 @@
import 'react-native-gesture-handler';
export { default } from './src/index';

View File

@@ -31,6 +31,10 @@ module.exports = {
'@babel/runtime',
'react',
'react-native',
'react-native-gesture-handler',
'react-native-reanimated',
'react-native-safe-area-view',
'react-native-tab-view',
'shortid',
],
},

View File

@@ -21,7 +21,10 @@
"react": "16.8.3",
"react-dom": "^16.8.3",
"react-native": "https://github.com/expo/react-native/archive/sdk-34.0.0.tar.gz",
"react-native-gesture-handler": "~1.3.0",
"react-native-paper": "3.0.0-alpha.3",
"react-native-reanimated": "~1.1.0",
"react-native-tab-view": "2.7.1",
"react-native-web": "^0.11.4",
"scheduler": "^0.14.0",
"shortid": "^2.2.14"
@@ -36,6 +39,7 @@
},
"resolutions": {
"react": "16.8.3",
"react-dom": "^16.8.3"
"react-dom": "^16.8.3",
"react-native-safe-area-view": "0.14.6"
}
}

View File

@@ -1,105 +0,0 @@
/* eslint-disable react-native/no-inline-styles */
import * as React from 'react';
import { Text, View } from 'react-native';
import {
useNavigationBuilder,
NavigationProp,
ParamListBase,
createNavigator,
} from '@navigation-ex/core';
import {
StackRouter,
StackRouterOptions,
StackNavigationState,
} from '@navigation-ex/routers';
type Props = StackRouterOptions & {
children: React.ReactNode;
};
export type StackNavigationOptions = {
/**
* Title text for the screen.
*/
title?: string;
};
export type StackNavigationProp<
ParamList extends ParamListBase,
RouteName extends keyof ParamList = string
> = NavigationProp<
ParamList,
RouteName,
StackNavigationState,
StackNavigationOptions
> & {
/**
* Push a new screen onto the stack.
*
* @param name Name of the route for the tab.
* @param [params] Params object for the route.
*/
push<RouteName extends keyof ParamList>(
...args: ParamList[RouteName] extends void
? [RouteName]
: [RouteName, ParamList[RouteName]]
): void;
/**
* Pop a screen from the stack.
*/
pop(count?: number): void;
/**
* Pop to the first route in the stack, dismissing all other screens.
*/
popToTop(): void;
};
export function StackNavigator(props: Props) {
const { state, descriptors } = useNavigationBuilder<
StackNavigationState,
StackNavigationOptions,
StackRouterOptions
>(StackRouter, props);
return (
<View>
{state.routes.map((route, i) => (
<View
key={route.key}
style={{
position: 'absolute',
margin: 20,
left: i * 20,
top: i * 20,
padding: 10,
height: 480,
width: 320,
backgroundColor: 'white',
borderRadius: 3,
}}
>
{descriptors[route.key].render()}
</View>
))}
<View
style={{
position: 'absolute',
left: 40,
width: 120,
padding: 10,
backgroundColor: 'tomato',
borderRadius: 3,
}}
>
<Text>{descriptors[state.routes[state.index].key].options.title}</Text>
</View>
</View>
);
}
export default createNavigator<StackNavigationOptions, typeof StackNavigator>(
StackNavigator
);

View File

@@ -1,78 +0,0 @@
/* eslint-disable react-native/no-inline-styles */
import * as React from 'react';
import { View } from 'react-native';
import {
useNavigationBuilder,
NavigationProp,
ParamListBase,
createNavigator,
} from '@navigation-ex/core';
import {
TabRouter,
TabRouterOptions,
TabNavigationState,
} from '@navigation-ex/routers';
type Props = TabRouterOptions & {
children: React.ReactNode;
};
export type TabNavigationOptions = {
/**
* Title text for the screen.
*/
title?: string;
};
export type TabNavigationProp<
ParamList extends ParamListBase,
RouteName extends keyof ParamList = string
> = NavigationProp<
ParamList,
RouteName,
TabNavigationState,
TabNavigationOptions
> & {
/**
* Jump to an existing tab.
*
* @param name Name of the route for the tab.
* @param [params] Params object for the route.
*/
jumpTo<RouteName extends Extract<keyof ParamList, string>>(
...args: ParamList[RouteName] extends void
? [RouteName]
: [RouteName, ParamList[RouteName]]
): void;
};
export function TabNavigator(props: Props) {
const { state, descriptors } = useNavigationBuilder<
TabNavigationState,
TabNavigationOptions,
TabRouterOptions
>(TabRouter, props);
return (
<View style={{ display: 'flex', flexDirection: 'row', height: '100%' }}>
{state.routes.map((route, i, self) => (
<View
key={route.key}
style={{
width: `${100 / self.length}%`,
padding: 10,
borderRadius: 3,
backgroundColor: i === state.index ? 'tomato' : 'white',
}}
>
{descriptors[route.key].render()}
</View>
))}
</View>
);
}
export default createNavigator<TabNavigationOptions, typeof TabNavigator>(
TabNavigator
);

View File

@@ -16,8 +16,12 @@ import {
InitialState,
useFocusEffect,
} from '@navigation-ex/core';
import createStackNavigator, { StackNavigationProp } from './StackNavigator';
import createTabNavigator, { TabNavigationProp } from './TabNavigator';
import createStackNavigator, {
StackNavigationProp,
} from '@navigation-ex/stack';
import createMaterialTopTabNavigator, {
MaterialTopTabNavigationProp,
} from '@navigation-ex/material-top-tabs';
type StackParamList = {
first: { author: string };
@@ -34,7 +38,7 @@ YellowBox.ignoreWarnings(['Require cycle:', 'Warning: Async Storage']);
const Stack = createStackNavigator<StackParamList>();
const Tab = createTabNavigator<TabParamList>();
const Tab = createMaterialTopTabNavigator<TabParamList>();
const First = ({
navigation,
@@ -111,7 +115,7 @@ const Fourth = ({
navigation,
}: {
navigation: CompositeNavigationProp<
TabNavigationProp<TabParamList, 'fourth'>,
MaterialTopTabNavigationProp<TabParamList, 'fourth'>,
StackNavigationProp<StackParamList>
>;
}) => (
@@ -129,7 +133,7 @@ const Fifth = ({
navigation,
}: {
navigation: CompositeNavigationProp<
TabNavigationProp<TabParamList, 'fifth'>,
MaterialTopTabNavigationProp<TabParamList, 'fifth'>,
StackNavigationProp<StackParamList>
>;
}) => (
@@ -192,8 +196,16 @@ export default function App() {
<Stack.Screen name="third" options={{ title: 'Baz' }}>
{() => (
<Tab.Navigator initialRouteName="fifth">
<Tab.Screen name="fourth" component={Fourth} />
<Tab.Screen name="fifth" component={Fifth} />
<Tab.Screen
name="fourth"
component={Fourth}
options={{ title: 'This' }}
/>
<Tab.Screen
name="fifth"
component={Fifth}
options={{ title: 'That' }}
/>
</Tab.Navigator>
)}
</Stack.Screen>