mirror of
https://github.com/zhigang1992/react-navigation.git
synced 2026-04-26 05:25:30 +08:00
feat: add backBehavior to TabRouter
This commit is contained in:
committed by
Satyajit Sahoo
parent
0e2754df5b
commit
cc76c69e70
@@ -14,8 +14,7 @@ import {
|
||||
DefaultRouterOptions,
|
||||
} from '../src/index';
|
||||
|
||||
type Props = {
|
||||
initialRouteName?: string;
|
||||
type Props = DefaultRouterOptions & {
|
||||
children: React.ReactNode;
|
||||
};
|
||||
|
||||
|
||||
@@ -14,8 +14,7 @@ import {
|
||||
DefaultRouterOptions,
|
||||
} from '../src/index';
|
||||
|
||||
type Props = {
|
||||
initialRouteName?: string;
|
||||
type Props = TabRouterOptions & {
|
||||
children: React.ReactNode;
|
||||
};
|
||||
|
||||
@@ -24,6 +23,10 @@ type Action = {
|
||||
payload: { name: string; params?: object };
|
||||
};
|
||||
|
||||
export type TabRouterOptions = DefaultRouterOptions & {
|
||||
backBehavior?: 'initialRoute' | 'order' | 'history' | 'none';
|
||||
};
|
||||
|
||||
export type TabNavigationOptions = {
|
||||
/**
|
||||
* Title text for the screen.
|
||||
@@ -31,13 +34,20 @@ export type TabNavigationOptions = {
|
||||
title?: string;
|
||||
};
|
||||
|
||||
export type TabNavigationState = NavigationState & {
|
||||
/**
|
||||
* List of previously visited route keys.
|
||||
*/
|
||||
routeKeyHistory: string[];
|
||||
};
|
||||
|
||||
export type TabNavigationProp<
|
||||
ParamList extends ParamListBase,
|
||||
RouteName extends keyof ParamList = string
|
||||
> = NavigationProp<
|
||||
ParamList,
|
||||
RouteName,
|
||||
NavigationState,
|
||||
TabNavigationState,
|
||||
TabNavigationOptions
|
||||
> & {
|
||||
/**
|
||||
@@ -53,20 +63,24 @@ export type TabNavigationProp<
|
||||
): void;
|
||||
};
|
||||
|
||||
function TabRouter(options: DefaultRouterOptions) {
|
||||
const router: Router<NavigationState, Action | CommonAction> = {
|
||||
function TabRouter({
|
||||
initialRouteName,
|
||||
backBehavior = 'history',
|
||||
}: TabRouterOptions) {
|
||||
const router: Router<TabNavigationState, Action | CommonAction> = {
|
||||
...BaseRouter,
|
||||
|
||||
getInitialState({ routeNames, routeParamList }) {
|
||||
const index =
|
||||
options.initialRouteName === undefined
|
||||
initialRouteName === undefined
|
||||
? 0
|
||||
: routeNames.indexOf(options.initialRouteName);
|
||||
: routeNames.indexOf(initialRouteName);
|
||||
|
||||
return {
|
||||
key: `tab-${shortid()}`,
|
||||
index,
|
||||
routeNames,
|
||||
routeKeyHistory: [],
|
||||
routes: routeNames.map(name => ({
|
||||
name,
|
||||
key: `${name}-${shortid()}`,
|
||||
@@ -115,7 +129,13 @@ function TabRouter(options: DefaultRouterOptions) {
|
||||
return state;
|
||||
}
|
||||
|
||||
return { ...state, index };
|
||||
return {
|
||||
...state,
|
||||
routeKeyHistory: [
|
||||
...new Set([...state.routeKeyHistory, state.routes[state.index].key]),
|
||||
],
|
||||
index,
|
||||
};
|
||||
},
|
||||
|
||||
getStateForAction(state, action) {
|
||||
@@ -140,6 +160,12 @@ function TabRouter(options: DefaultRouterOptions) {
|
||||
|
||||
return {
|
||||
...state,
|
||||
routeKeyHistory: [
|
||||
...new Set([
|
||||
...state.routeKeyHistory,
|
||||
state.routes[state.index].key,
|
||||
]),
|
||||
],
|
||||
routes:
|
||||
action.payload.params !== undefined
|
||||
? state.routes.map((route, i) =>
|
||||
@@ -158,6 +184,52 @@ function TabRouter(options: DefaultRouterOptions) {
|
||||
};
|
||||
}
|
||||
|
||||
case 'GO_BACK':
|
||||
switch (backBehavior) {
|
||||
case 'initialRoute': {
|
||||
const index = initialRouteName
|
||||
? state.routeNames.indexOf(initialRouteName)
|
||||
: 0;
|
||||
|
||||
if (index === -1 || index === state.index) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return { ...state, index };
|
||||
}
|
||||
|
||||
case 'order':
|
||||
if (state.index === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
...state,
|
||||
index: state.index - 1,
|
||||
};
|
||||
|
||||
case 'history': {
|
||||
const previousKey =
|
||||
state.routeKeyHistory[state.routeKeyHistory.length - 1];
|
||||
const index = state.routes.findIndex(
|
||||
route => route.key === previousKey
|
||||
);
|
||||
|
||||
if (index === -1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
...state,
|
||||
routeKeyHistory: state.routeKeyHistory.slice(0, -1),
|
||||
index,
|
||||
};
|
||||
}
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
default:
|
||||
return BaseRouter.getStateForAction(state, action);
|
||||
}
|
||||
@@ -183,9 +255,9 @@ function TabRouter(options: DefaultRouterOptions) {
|
||||
|
||||
export function TabNavigator(props: Props) {
|
||||
const { state, descriptors } = useNavigationBuilder<
|
||||
NavigationState,
|
||||
TabNavigationState,
|
||||
TabNavigationOptions,
|
||||
DefaultRouterOptions
|
||||
TabRouterOptions
|
||||
>(TabRouter, props);
|
||||
|
||||
return (
|
||||
|
||||
@@ -325,8 +325,8 @@ export type RouteProp<
|
||||
});
|
||||
|
||||
export type CompositeNavigationProp<
|
||||
A extends NavigationProp<ParamListBase>,
|
||||
B extends NavigationHelpersCommon<ParamListBase>
|
||||
A extends NavigationProp<ParamListBase, string, any, any>,
|
||||
B extends NavigationHelpersCommon<ParamListBase, any>
|
||||
> = Omit<A & B, keyof NavigationProp<any>> &
|
||||
NavigationProp<
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user