feat: add basic nesting example

This commit is contained in:
satyajit.happy
2019-06-09 20:19:50 +02:00
parent a78bbbc569
commit 0514ca7fca
5 changed files with 152 additions and 15 deletions

View File

@@ -10,6 +10,7 @@ import {
type Props = {
initialRouteName?: string;
navigation?: NavigationProp;
children: React.ReactElement[];
};
@@ -42,6 +43,7 @@ const StackRouter = {
switch (action.type) {
case 'PUSH':
return {
...state,
index: state.index + 1,
routes: [
...state.routes,
@@ -54,6 +56,7 @@ const StackRouter = {
case 'POP':
return state.index > 0
? {
...state,
index: state.index - 1,
routes: state.routes.slice(0, state.routes.length - 1),
}
@@ -73,13 +76,10 @@ const StackRouter = {
},
};
export default function StackNavigator({ initialRouteName, children }: Props) {
export default function StackNavigator(props: Props) {
// The `navigation` object contains the navigation state and some helpers (e.g. push, pop)
// The `descriptors` object contains `navigation` objects for children routes and helper for rendering a screen
const { navigation, descriptors } = useNavigationBuilder(StackRouter, {
initialRouteName,
children,
});
const { navigation, descriptors } = useNavigationBuilder(StackRouter, props);
return (
<div style={{ position: 'relative' }}>

82
example/TabNavigator.tsx Normal file
View File

@@ -0,0 +1,82 @@
/* eslint-disable react-native/no-inline-styles */
import * as React from 'react';
import shortid from 'shortid';
import {
useNavigationBuilder,
NavigationState,
NavigationProp,
} from '../src/index';
type Props = {
initialRouteName?: string;
navigation?: NavigationProp;
children: React.ReactElement[];
};
type Action = {
type: 'JUMP_TO';
payload: { name: string };
};
export type TabNavigationProp = NavigationProp<typeof TabRouter>;
const TabRouter = {
getInitialState(
routeNames: string[],
{ initialRouteName = routeNames[0] }: { initialRouteName?: string }
) {
const index = routeNames.indexOf(initialRouteName);
return {
index,
routes: routeNames.map(name => ({
name,
key: `${name}-${shortid()}`,
})),
};
},
reduce(state: NavigationState, action: Action) {
switch (action.type) {
case 'JUMP_TO':
return {
...state,
index: state.routes.findIndex(
route => route.name === action.payload.name
),
};
default:
return state;
}
},
actions: {
jumpTo(name: string): Action {
return { type: 'JUMP_TO', payload: { name } };
},
},
};
export default function TabNavigator(props: Props) {
// The `navigation` object contains the navigation state and some helpers (e.g. push, pop)
// The `descriptors` object contains `navigation` objects for children routes and helper for rendering a screen
const { navigation, descriptors } = useNavigationBuilder(TabRouter, props);
return (
<div style={{ display: 'flex', flexDirection: 'row' }}>
{navigation.state.routes.map((route, i, self) => (
<div
key={route.key}
style={{
width: `${100 / self.length}%`,
backgroundColor: i === navigation.state.index ? 'tomato' : 'white',
border: '1px solid black',
}}
>
{descriptors[route.name].render()}
</div>
))}
</div>
);
}

View File

@@ -3,6 +3,7 @@ import * as React from 'react';
import { render } from 'react-dom';
import { NavigationContainer, Screen } from '../src';
import StackNavigator, { StackNavigationProp } from './StackNavigator';
import TabNavigator, { TabNavigationProp } from './TabNavigator';
const First = ({ navigation }: { navigation: StackNavigationProp }) => (
<div>
@@ -10,6 +11,9 @@ const First = ({ navigation }: { navigation: StackNavigationProp }) => (
<button type="button" onClick={() => navigation.push('second')}>
Push second
</button>
<button type="button" onClick={() => navigation.push('third')}>
Push third
</button>
<button type="button" onClick={() => navigation.pop()}>
Go back
</button>
@@ -28,6 +32,44 @@ const Second = ({ navigation }: { navigation: StackNavigationProp }) => (
</div>
);
const Fourth = ({
navigation,
}: {
navigation: TabNavigationProp & StackNavigationProp;
}) => (
<div>
<h1>Fourth route</h1>
<button type="button" onClick={() => navigation.jumpTo('fifth')}>
Jump to fifth
</button>
<button type="button" onClick={() => navigation.push('first')}>
Push first
</button>
<button type="button" onClick={() => navigation.pop()}>
Go back
</button>
</div>
);
const Fifth = ({
navigation,
}: {
navigation: TabNavigationProp & StackNavigationProp;
}) => (
<div>
<h1>Fifth route</h1>
<button type="button" onClick={() => navigation.jumpTo('fourth')}>
Jump to fourth
</button>
<button type="button" onClick={() => navigation.push('second')}>
Push second
</button>
<button type="button" onClick={() => navigation.pop()}>
Go back
</button>
</div>
);
const routes =
location.pathname !== '/'
? location.pathname
@@ -49,6 +91,14 @@ function App() {
<StackNavigator>
<Screen name="first" component={First} />
<Screen name="second" component={Second} />
<Screen name="third">
{props => (
<TabNavigator {...props}>
<Screen name="fourth" component={Fourth} />
<Screen name="fifth" component={Fifth} />
</TabNavigator>
)}
</Screen>
</StackNavigator>
</NavigationContainer>
);