diff --git a/example/StackNavigator.tsx b/example/StackNavigator.tsx index 5190e283..6df3d3c0 100644 --- a/example/StackNavigator.tsx +++ b/example/StackNavigator.tsx @@ -8,33 +8,46 @@ import { NavigationProp, CommonAction, InitialState, + ScreenProps, + ParamListBase, } from '../src/index'; type Props = { initialRouteName?: string; - navigation?: NavigationProp; children: React.ReactElement[]; }; type Action = | { type: 'PUSH'; - payload: { name: string }; + payload: { name: string; params?: object }; } | { type: 'POP' }; -export type StackNavigationProp = NavigationProp; +export type StackNavigationProp< + ParamList extends ParamListBase, + RouteName extends keyof ParamList = string +> = NavigationProp & { + push( + ...args: ParamList[RouteName] extends void + ? [RouteName] + : [RouteName, ParamList[RouteName]] + ): void; + pop(): void; +}; const StackRouter = { normalize({ + screens, currentState, - routeNames, - initialRouteName = routeNames[0], + initialRouteName = Object.keys(screens)[0], }: { + screens: { [key: string]: ScreenProps }; currentState?: InitialState | NavigationState; - routeNames: string[]; initialRouteName?: string; }): NavigationState { + const routeNames = Object.keys(screens); + let state = currentState; if (state === undefined) { @@ -45,6 +58,7 @@ const StackRouter = { routes: routeNames.slice(0, index + 1).map(name => ({ name, key: `${name}-${shortid()}`, + params: screens[name].initialParams, })), }; } @@ -72,8 +86,9 @@ const StackRouter = { routes: [ ...state.routes, { - name: action.payload.name, key: `${action.payload.name}-${shortid()}`, + name: action.payload.name, + params: action.payload.params, }, ], }; @@ -97,14 +112,19 @@ const StackRouter = { if (index === -1) { return StackRouter.reduce(state, { type: 'PUSH', - payload: { name: action.payload.name }, + payload: action.payload, }); } return { ...state, index, - routes: state.routes.slice(0, index + 1), + routes: [ + ...state.routes.slice(0, index), + action.payload.params !== undefined + ? { ...state.routes[index], params: action.payload.params } + : state.routes[index], + ], }; } diff --git a/example/TabNavigator.tsx b/example/TabNavigator.tsx index 5886c5ec..263f5beb 100644 --- a/example/TabNavigator.tsx +++ b/example/TabNavigator.tsx @@ -8,31 +8,43 @@ import { NavigationProp, CommonAction, InitialState, + ScreenProps, + ParamListBase, } from '../src/index'; type Props = { initialRouteName?: string; - navigation?: NavigationProp; children: React.ReactElement[]; }; type Action = { type: 'JUMP_TO'; - payload: { name: string }; + payload: { name: string; params?: object }; }; -export type TabNavigationProp = NavigationProp; +export type TabNavigationProp< + ParamList extends ParamListBase, + RouteName extends keyof ParamList = string +> = NavigationProp & { + jumpTo( + ...args: ParamList[RouteName] extends void + ? [RouteName] + : [RouteName, ParamList[RouteName]] + ): void; +}; const TabRouter = { normalize({ + screens, currentState, - routeNames, - initialRouteName = routeNames[0], + initialRouteName = Object.keys(screens)[0], }: { - routeNames: string[]; + screens: { [key: string]: ScreenProps }; currentState?: InitialState | NavigationState; initialRouteName?: string; }): NavigationState { + const routeNames = Object.keys(screens); + let state = currentState; if (state === undefined) { @@ -43,6 +55,7 @@ const TabRouter = { routes: routeNames.map(name => ({ name, key: `${name}-${shortid()}`, + params: screens[name].initialParams, })), }; } @@ -76,6 +89,17 @@ const TabRouter = { return { ...state, + routes: + action.payload.params !== undefined + ? state.routes.map((route, i) => + i === index + ? { + ...route, + params: action.payload.params, + } + : route + ) + : state.routes, index, }; } diff --git a/example/index.tsx b/example/index.tsx index 6e513b9f..0a935a6b 100644 --- a/example/index.tsx +++ b/example/index.tsx @@ -1,29 +1,57 @@ import shortid from 'shortid'; import * as React from 'react'; import { render } from 'react-dom'; -import { NavigationContainer, Screen } from '../src'; +import { NavigationContainer, Screen, CompositeNavigationProp } from '../src'; import StackNavigator, { StackNavigationProp } from './StackNavigator'; import TabNavigator, { TabNavigationProp } from './TabNavigator'; -const First = ({ navigation }: { navigation: StackNavigationProp }) => ( +type StackParamList = { + first: { author: string }; + second: void; + third: void; +}; + +type TabParamList = { + fourth: void; + fifth: void; +}; + +const First = ({ + navigation, +}: { + navigation: StackNavigationProp; +}) => (
-

First

+

First, {navigation.state.params.author}

+
); -const Second = ({ navigation }: { navigation: StackNavigationProp }) => ( +const Second = ({ + navigation, +}: { + navigation: StackNavigationProp; +}) => (

Second

- - -