refactor: move types and base router to routers package

This commit is contained in:
Satyajit Sahoo
2020-02-10 15:53:38 +01:00
parent 7160a511e6
commit 86c39d2e0e
91 changed files with 447 additions and 434 deletions

View File

@@ -4,3 +4,7 @@ dist/
lib/
web-build/
web-report/
.expo/
.yarn/
.vscode/

View File

@@ -30,12 +30,12 @@
"clean": "del lib"
},
"dependencies": {
"@react-navigation/routers": "^5.0.0",
"color": "^3.1.2",
"react-native-iphone-x-helper": "^1.2.1"
},
"devDependencies": {
"@react-native-community/bob": "^0.9.3",
"@react-navigation/native": "^5.0.0",
"@types/color": "^3.0.1",
"@types/react": "^16.9.19",
"@types/react-native": "^0.60.30",

View File

@@ -3,12 +3,10 @@ import {
useNavigationBuilder,
createNavigatorFactory,
DefaultNavigatorOptions,
} from '@react-navigation/native';
import {
TabRouter,
TabRouterOptions,
TabNavigationState,
} from '@react-navigation/routers';
} from '@react-navigation/native';
import BottomTabView from '../views/BottomTabView';
import {
BottomTabNavigationConfig,

View File

@@ -10,8 +10,8 @@ import {
NavigationProp,
ParamListBase,
Descriptor,
TabNavigationState,
} from '@react-navigation/native';
import { TabNavigationState } from '@react-navigation/routers';
export type BottomTabNavigationEventMap = {
/**

View File

@@ -1,8 +1,7 @@
import * as React from 'react';
import { View, StyleSheet } from 'react-native';
import { TabNavigationState } from '@react-navigation/routers';
import { useTheme } from '@react-navigation/native';
import { TabNavigationState, useTheme } from '@react-navigation/native';
// eslint-disable-next-line import/no-unresolved
import { ScreenContainer } from 'react-native-screens';

View File

@@ -2,8 +2,8 @@
"extends": "../../tsconfig",
"references": [
{ "path": "../core" },
{ "path": "../native" },
{ "path": "../routers" }
{ "path": "../routers" },
{ "path": "../native" }
],
"compilerOptions": {
"outDir": "./lib/typescript"

View File

@@ -24,11 +24,10 @@
"prepare": "bob build",
"clean": "del lib"
},
"dependencies": {
"@react-navigation/routers": "^5.0.0"
},
"dependencies": {},
"devDependencies": {
"@react-native-community/bob": "^0.9.3",
"@react-navigation/native": "^5.0.0",
"@types/react": "^16.9.19",
"react": "~16.9.0",
"typescript": "^3.7.5"

View File

@@ -1,4 +1,4 @@
import { DrawerActions, DrawerActionType } from '@react-navigation/routers';
import { DrawerActions, DrawerActionType } from '@react-navigation/native';
export function openDrawer(): DrawerActionType {
return DrawerActions.openDrawer();

View File

@@ -1,5 +1,8 @@
import { CommonActions } from '@react-navigation/native';
import { StackActions, StackActionType } from '@react-navigation/routers';
import {
CommonActions,
StackActions,
StackActionType,
} from '@react-navigation/native';
export function reset(): CommonActions.Action {
throw new Error(

View File

@@ -1,4 +1,4 @@
import { TabActions, TabActionType } from '@react-navigation/routers';
import { TabActions, TabActionType } from '@react-navigation/native';
export function jumpTo({
routeName,

View File

@@ -2,12 +2,10 @@ import {
useNavigationBuilder,
createNavigatorFactory,
DefaultNavigatorOptions,
} from '@react-navigation/native';
import {
TabRouter,
TabRouterOptions,
TabNavigationState,
} from '@react-navigation/routers';
} from '@react-navigation/native';
import createCompatNavigatorFactory from './createCompatNavigatorFactory';
type Props = DefaultNavigatorOptions<{}> & TabRouterOptions;

View File

@@ -2,8 +2,8 @@
"extends": "../../tsconfig",
"references": [
{ "path": "../core" },
{ "path": "../native" },
{ "path": "../routers" }
{ "path": "../routers" },
{ "path": "../native" }
],
"compilerOptions": {
"outDir": "./lib/typescript"

View File

@@ -29,6 +29,7 @@
"clean": "del lib"
},
"dependencies": {
"@react-navigation/routers": "^5.0.0",
"escape-string-regexp": "^2.0.0",
"query-string": "^6.10.1",
"react-is": "^16.12.0",

View File

@@ -1,5 +1,12 @@
import * as React from 'react';
import * as CommonActions from './CommonActions';
import {
CommonActions,
Route,
NavigationState,
InitialState,
PartialState,
NavigationAction,
} from '@react-navigation/routers';
import EnsureSingleNavigator from './EnsureSingleNavigator';
import NavigationBuilderContext from './NavigationBuilderContext';
import useFocusedListeners from './useFocusedListeners';
@@ -7,15 +14,7 @@ import useDevTools from './useDevTools';
import useStateGetters from './useStateGetters';
import isSerializable from './isSerializable';
import {
Route,
NavigationState,
InitialState,
PartialState,
NavigationAction,
NavigationContainerRef,
NavigationContainerProps,
} from './types';
import { NavigationContainerRef, NavigationContainerProps } from './types';
import useEventEmitter from './useEventEmitter';
type State = NavigationState | PartialState<NavigationState> | undefined;

View File

@@ -1,10 +1,10 @@
import * as React from 'react';
import {
NavigationAction,
NavigationHelpers,
NavigationState,
ParamListBase,
} from './types';
} from '@react-navigation/routers';
import { NavigationHelpers } from './types';
export type ChildActionListener = (
action: NavigationAction,

View File

@@ -1,5 +1,6 @@
import * as React from 'react';
import { NavigationProp, ParamListBase } from './types';
import { ParamListBase } from '@react-navigation/routers';
import { NavigationProp } from './types';
/**
* Context which holds the navigation prop for a screen.

View File

@@ -1,5 +1,5 @@
import * as React from 'react';
import { Route } from './types';
import { Route } from '@react-navigation/routers';
/**
* Context which holds the route prop for a screen.

View File

@@ -1,17 +1,16 @@
import * as React from 'react';
import {
Route,
ParamListBase,
NavigationState,
PartialState,
} from '@react-navigation/routers';
import { NavigationStateContext } from './BaseNavigationContainer';
import NavigationContext from './NavigationContext';
import NavigationRouteContext from './NavigationRouteContext';
import StaticContainer from './StaticContainer';
import EnsureSingleNavigator from './EnsureSingleNavigator';
import {
Route,
ParamListBase,
NavigationState,
NavigationProp,
RouteConfig,
PartialState,
} from './types';
import { NavigationProp, RouteConfig } from './types';
type Props<State extends NavigationState, ScreenOptions extends object> = {
screen: RouteConfig<ParamListBase, string, ScreenOptions>;

View File

@@ -1,4 +1,5 @@
import { RouteConfig, ParamListBase } from './types';
import { ParamListBase } from '@react-navigation/routers';
import { RouteConfig } from './types';
/**
* Empty component used for specifying route configuration.

View File

@@ -1,17 +1,17 @@
import * as React from 'react';
import { act, render } from 'react-native-testing-library';
import {
DefaultRouterOptions,
NavigationState,
Router,
} from '@react-navigation/routers';
import BaseNavigationContainer, {
NavigationStateContext,
} from '../BaseNavigationContainer';
import MockRouter, { MockActions } from './__fixtures__/MockRouter';
import useNavigationBuilder from '../useNavigationBuilder';
import Screen from '../Screen';
import {
DefaultRouterOptions,
NavigationState,
Router,
NavigationContainerRef,
} from '../types';
import { NavigationContainerRef } from '../types';
it('throws when getState is accessed without a container', () => {
expect.assertions(1);

View File

@@ -1,43 +0,0 @@
import * as React from 'react';
import { render } from 'react-native-testing-library';
import Screen from '../Screen';
import BaseNavigationContainer from '../BaseNavigationContainer';
import useNavigationBuilder from '../useNavigationBuilder';
import MockRouter, { MockRouterKey } from './__fixtures__/MockRouter';
beforeEach(() => (MockRouterKey.current = 0));
it('throws if NAVIGATE dispatched neither key nor name', () => {
const TestNavigator = (props: any) => {
const { state, descriptors } = useNavigationBuilder(MockRouter, props);
return descriptors[state.routes[state.index].key].render();
};
const FooScreen = (props: any) => {
React.useEffect(() => {
props.navigation.navigate({});
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
return null;
};
const onStateChange = jest.fn();
const element = (
<BaseNavigationContainer onStateChange={onStateChange}>
<TestNavigator initialRouteName="foo">
<Screen
name="foo"
component={FooScreen}
initialParams={{ count: 10 }}
/>
</TestNavigator>
</BaseNavigationContainer>
);
expect(() => render(element).update(element)).toThrowError(
'While calling navigate with an object as the argument, you need to specify name or key'
);
});

View File

@@ -1,13 +1,13 @@
import BaseRouter from '../../BaseRouter';
import {
BaseRouter,
Router,
CommonAction,
CommonNavigationAction,
NavigationState,
Route,
DefaultRouterOptions,
} from '../../types';
} from '@react-navigation/routers';
export type MockActions = CommonAction | { type: 'NOOP' | 'UPDATE' };
export type MockActions = CommonNavigationAction | { type: 'NOOP' | 'UPDATE' };
export const MockRouterKey = { current: 0 };

View File

@@ -1,11 +1,12 @@
import * as React from 'react';
import { render, act } from 'react-native-testing-library';
import { NavigationState } from '@react-navigation/routers';
import Screen from '../Screen';
import BaseNavigationContainer from '../BaseNavigationContainer';
import useNavigationBuilder from '../useNavigationBuilder';
import useNavigation from '../useNavigation';
import MockRouter, { MockRouterKey } from './__fixtures__/MockRouter';
import { NavigationState, NavigationContainerRef } from '../types';
import { NavigationContainerRef } from '../types';
beforeEach(() => (MockRouterKey.current = 0));

View File

@@ -1,5 +1,10 @@
import * as React from 'react';
import { render, act } from 'react-native-testing-library';
import {
DefaultRouterOptions,
NavigationState,
Router,
} from '@react-navigation/routers';
import useNavigationBuilder from '../useNavigationBuilder';
import BaseNavigationContainer from '../BaseNavigationContainer';
import Screen from '../Screen';
@@ -7,7 +12,6 @@ import MockRouter, {
MockActions,
MockRouterKey,
} from './__fixtures__/MockRouter';
import { DefaultRouterOptions, NavigationState, Router } from '../types';
jest.useFakeTimers();

View File

@@ -1,10 +1,10 @@
import * as React from 'react';
import { render, act } from 'react-native-testing-library';
import { Router, NavigationState } from '@react-navigation/routers';
import useNavigationBuilder from '../useNavigationBuilder';
import BaseNavigationContainer from '../BaseNavigationContainer';
import Screen from '../Screen';
import MockRouter from './__fixtures__/MockRouter';
import { Router, NavigationState } from '../types';
it('fires focus and blur events in root navigator', () => {
const TestNavigator = React.forwardRef((props: any, ref: any): any => {

View File

@@ -1,11 +1,11 @@
import * as React from 'react';
import { render, act } from 'react-native-testing-library';
import { NavigationState } from '@react-navigation/routers';
import useNavigationBuilder from '../useNavigationBuilder';
import useNavigationState from '../useNavigationState';
import BaseNavigationContainer from '../BaseNavigationContainer';
import Screen from '../Screen';
import MockRouter from './__fixtures__/MockRouter';
import { NavigationState } from '../types';
it('gets the current navigation state', () => {
const TestNavigator = (props: any): any => {

View File

@@ -1,5 +1,10 @@
import * as React from 'react';
import { render } from 'react-native-testing-library';
import {
Router,
DefaultRouterOptions,
NavigationState,
} from '@react-navigation/routers';
import useNavigationBuilder from '../useNavigationBuilder';
import BaseNavigationContainer from '../BaseNavigationContainer';
import Screen from '../Screen';
@@ -7,7 +12,6 @@ import MockRouter, {
MockActions,
MockRouterKey,
} from './__fixtures__/MockRouter';
import { Router, DefaultRouterOptions, NavigationState } from '../types';
beforeEach(() => (MockRouterKey.current = 0));

View File

@@ -1,6 +1,7 @@
import * as React from 'react';
import { ParamListBase } from '@react-navigation/routers';
import Screen from './Screen';
import { ParamListBase, TypedNavigator } from './types';
import { TypedNavigator } from './types';
/**
* Higher order component to create a `Navigator` and `Screen` pair.

View File

@@ -1,4 +1,4 @@
import { PartialState, NavigationState } from './types';
import { PartialState, NavigationState } from '@react-navigation/routers';
type NavigateParams = {
screen?: string;

View File

@@ -1,5 +1,9 @@
import queryString from 'query-string';
import { NavigationState, PartialState, Route } from './types';
import {
NavigationState,
PartialState,
Route,
} from '@react-navigation/routers';
type State = NavigationState | Omit<PartialState<NavigationState>, 'stale'>;

View File

@@ -1,6 +1,10 @@
import escape from 'escape-string-regexp';
import queryString from 'query-string';
import { NavigationState, PartialState, InitialState } from './types';
import {
NavigationState,
PartialState,
InitialState,
} from '@react-navigation/routers';
type ParseConfig = Record<string, (value: string) => any>;

View File

@@ -1,8 +1,5 @@
import * as CommonActions from './CommonActions';
export * from '@react-navigation/routers';
export { CommonActions };
export { default as BaseRouter } from './BaseRouter';
export { default as BaseNavigationContainer } from './BaseNavigationContainer';
export { default as createNavigatorFactory } from './createNavigatorFactory';

View File

@@ -1,105 +1,13 @@
import * as CommonActions from './CommonActions';
import * as React from 'react';
export type CommonAction = CommonActions.Action;
export type NavigationState = {
/**
* Unique key for the navigation state.
*/
key: string;
/**
* Index of the currently focused route.
*/
index: number;
/**
* List of valid route names as defined in the screen components.
*/
routeNames: string[];
/**
* Alternative entries for history.
*/
history?: unknown[];
/**
* List of rendered routes.
*/
routes: (Route<string> & {
state?: NavigationState | PartialState<NavigationState>;
})[];
/**
* Custom type for the state, whether it's for tab, stack, drawer etc.
* During rehydration, the state will be discarded if type doesn't match with router type.
* It can also be used to detect the type of the navigator we're dealing with.
*/
type: string;
/**
* Whether the navigation state has been rehydrated.
*/
stale: false;
};
export type InitialState = Partial<
Omit<NavigationState, 'stale' | 'routes'>
> & {
routes: (Omit<Route<string>, 'key'> & { state?: InitialState })[];
};
export type PartialState<State extends NavigationState> = Partial<
Omit<State, 'stale' | 'type' | 'key' | 'routes' | 'routeNames'>
> & {
stale?: true;
type?: string;
routes: (Omit<Route<string>, 'key'> & {
key?: string;
state?: InitialState;
})[];
};
export type Route<RouteName extends string> = {
/**
* Unique key for the route.
*/
key: string;
/**
* User-provided name for the route.
*/
name: RouteName;
/**
* Params for the route.
*/
params?: object;
};
export type NavigationAction = {
/**
* Type of the action (e.g. `NAVIGATE`)
*/
type: string;
/**
* Additional data for the action
*/
payload?: object;
/**
* Key of the route which dispatched this action.
*/
source?: string;
/**
* Key of the navigator which should handle this action.
*/
target?: string;
};
export type ActionCreators<Action extends NavigationAction> = {
[key: string]: (...args: any) => Action;
};
export type DefaultRouterOptions = {
/**
* Name of the route to focus by on initial render.
* If not specified, usually the first route is used.
*/
initialRouteName?: string;
};
import {
DefaultRouterOptions,
NavigationState,
NavigationAction,
InitialState,
PartialState,
Route,
ParamListBase,
} from '@react-navigation/routers';
export type DefaultNavigatorOptions<
ScreenOptions extends object
@@ -120,97 +28,6 @@ export type DefaultNavigatorOptions<
}) => ScreenOptions);
};
export type RouterFactory<
State extends NavigationState,
Action extends NavigationAction,
RouterOptions extends DefaultRouterOptions
> = (options: RouterOptions) => Router<State, Action>;
export type RouterConfigOptions = {
routeNames: string[];
routeParamList: ParamListBase;
};
export type Router<
State extends NavigationState,
Action extends NavigationAction
> = {
/**
* Type of the router. Should match the `type` property in state.
* If the type doesn't match, the state will be discarded during rehydration.
*/
type: State['type'];
/**
* Initialize the navigation state.
*
* @param options.routeNames List of valid route names as defined in the screen components.
* @param options.routeParamsList Object containing params for each route.
*/
getInitialState(options: RouterConfigOptions): State;
/**
* Rehydrate the full navigation state from a given partial state.
*
* @param partialState Navigation state to rehydrate from.
* @param options.routeNames List of valid route names as defined in the screen components.
* @param options.routeParamsList Object containing params for each route.
*/
getRehydratedState(
partialState: PartialState<State> | State,
options: RouterConfigOptions
): State;
/**
* Take the current state and updated list of route names, and return a new state.
*
* @param state State object to update.
* @param options.routeNames New list of route names.
* @param options.routeParamsList Object containing params for each route.
*/
getStateForRouteNamesChange(
state: State,
options: RouterConfigOptions
): State;
/**
* Take the current state and key of a route, and return a new state with the route focused
*
* @param state State object to apply the action on.
* @param key Key of the route to focus.
*/
getStateForRouteFocus(state: State, key: string): State;
/**
* Take the current state and action, and return a new state.
* If the action cannot be handled, return `null`.
*
* @param state State object to apply the action on.
* @param action Action object to apply.
* @param options.routeNames List of valid route names as defined in the screen components.
* @param options.routeParamsList Object containing params for each route.
*/
getStateForAction(
state: State,
action: Action,
options: RouterConfigOptions
): State | PartialState<State> | null;
/**
* Whether the action should also change focus in parent navigator
*
* @param action Action object to check.
*/
shouldActionChangeFocus(action: NavigationAction): boolean;
/**
* Action creators for the router.
*/
actionCreators?: ActionCreators<Action>;
};
export type ParamListBase = Record<string, object | undefined>;
export type EventMapBase = Record<
string,
{ data?: any; canPreventDefault?: boolean }

View File

@@ -1,4 +1,10 @@
import * as React from 'react';
import {
NavigationAction,
NavigationState,
ParamListBase,
Router,
} from '@react-navigation/routers';
import SceneView from './SceneView';
import NavigationBuilderContext, {
ChildActionListener,
@@ -7,16 +13,7 @@ import NavigationBuilderContext, {
} from './NavigationBuilderContext';
import { NavigationEventEmitter } from './useEventEmitter';
import useNavigationCache from './useNavigationCache';
import {
Descriptor,
NavigationAction,
NavigationHelpers,
NavigationState,
ParamListBase,
RouteConfig,
RouteProp,
Router,
} from './types';
import { Descriptor, NavigationHelpers, RouteConfig, RouteProp } from './types';
type Options<State extends NavigationState, ScreenOptions extends object> = {
state: State;

View File

@@ -1,5 +1,9 @@
import * as React from 'react';
import { NavigationState, NavigationAction, PartialState } from './types';
import {
NavigationState,
NavigationAction,
PartialState,
} from '@react-navigation/routers';
type State = NavigationState | PartialState<NavigationState> | undefined;

View File

@@ -1,7 +1,7 @@
import * as React from 'react';
import { NavigationState } from '@react-navigation/routers';
import NavigationContext from './NavigationContext';
import { NavigationEventEmitter } from './useEventEmitter';
import { NavigationState } from './types';
type Options = {
state: NavigationState;

View File

@@ -1,9 +1,10 @@
import * as React from 'react';
import { ParamListBase } from '@react-navigation/routers';
import NavigationBuilderContext, {
FocusedNavigationCallback,
FocusedNavigationListener,
} from './NavigationBuilderContext';
import { NavigationHelpers, ParamListBase } from './types';
import { NavigationHelpers } from './types';
type Options = {
navigation: NavigationHelpers<ParamListBase>;

View File

@@ -1,6 +1,7 @@
import * as React from 'react';
import { ParamListBase } from '@react-navigation/routers';
import NavigationContext from './NavigationContext';
import { NavigationProp, ParamListBase } from './types';
import { NavigationProp } from './types';
/**
* Hook to access the navigation prop of the parent screen anywhere.

View File

@@ -1,9 +1,18 @@
import * as React from 'react';
import { isValidElementType } from 'react-is';
import {
CommonActions,
DefaultRouterOptions,
NavigationState,
ParamListBase,
Router,
RouterFactory,
PartialState,
NavigationAction,
} from '@react-navigation/routers';
import { NavigationStateContext } from './BaseNavigationContainer';
import NavigationRouteContext from './NavigationRouteContext';
import Screen from './Screen';
import { navigate } from './CommonActions';
import useEventEmitter from './useEventEmitter';
import useRegisterNavigator from './useRegisterNavigator';
import useDescriptors from './useDescriptors';
@@ -15,16 +24,9 @@ import useChildActionListeners from './useChildActionListeners';
import useFocusedListeners from './useFocusedListeners';
import useFocusedListenersChildrenAdapter from './useFocusedListenersChildrenAdapter';
import {
DefaultRouterOptions,
DefaultNavigatorOptions,
NavigationState,
ParamListBase,
RouteConfig,
Router,
RouterFactory,
PartialState,
PrivateValueStore,
NavigationAction,
} from './types';
import useStateGetters from './useStateGetters';
import useOnGetState from './useOnGetState';
@@ -292,7 +294,7 @@ export default function useNavigationBuilder<
// The update should be limited to current navigator only, so we call the router manually
const updatedState = router.getStateForAction(
state,
navigate(route.params.screen, route.params.params),
CommonActions.navigate(route.params.screen, route.params.params),
{
routeNames,
routeParamList,

View File

@@ -1,16 +1,15 @@
import * as React from 'react';
import * as CommonActions from './CommonActions';
import { NavigationEventEmitter } from './useEventEmitter';
import NavigationContext from './NavigationContext';
import {
CommonActions,
NavigationAction,
NavigationHelpers,
NavigationProp,
ParamListBase,
NavigationState,
Router,
} from './types';
} from '@react-navigation/routers';
import { NavigationEventEmitter } from './useEventEmitter';
import NavigationContext from './NavigationContext';
import { NavigationHelpers, NavigationProp } from './types';
type Options<State extends NavigationState> = {
state: State;

View File

@@ -1,17 +1,15 @@
import * as React from 'react';
import * as CommonActions from './CommonActions';
import NavigationContext from './NavigationContext';
import { NavigationStateContext } from './BaseNavigationContainer';
import { NavigationEventEmitter } from './useEventEmitter';
import {
NavigationHelpers,
NavigationProp,
CommonActions,
NavigationAction,
NavigationState,
ParamListBase,
Router,
PrivateValueStore,
} from './types';
} from '@react-navigation/routers';
import NavigationContext from './NavigationContext';
import { NavigationStateContext } from './BaseNavigationContainer';
import { NavigationEventEmitter } from './useEventEmitter';
import { NavigationHelpers, NavigationProp, PrivateValueStore } from './types';
// This is to make TypeScript compiler happy
// eslint-disable-next-line babel/no-unused-expressions

View File

@@ -1,6 +1,6 @@
import * as React from 'react';
import { NavigationState } from '@react-navigation/routers';
import useNavigation from './useNavigation';
import { NavigationState } from './types';
type Selector<T> = (state: NavigationState) => T;

View File

@@ -1,14 +1,14 @@
import * as React from 'react';
import NavigationBuilderContext, {
ChildActionListener,
} from './NavigationBuilderContext';
import {
NavigationAction,
NavigationState,
PartialState,
Router,
RouterConfigOptions,
} from './types';
} from '@react-navigation/routers';
import NavigationBuilderContext, {
ChildActionListener,
} from './NavigationBuilderContext';
type Options = {
router: Router<NavigationState, NavigationAction>;

View File

@@ -1,6 +1,6 @@
import * as React from 'react';
import { NavigationState } from '@react-navigation/routers';
import NavigationBuilderContext from './NavigationBuilderContext';
import { NavigationState } from './types';
import NavigationRouteContext from './NavigationRouteContext';
export default function useOnGetState({

View File

@@ -1,6 +1,10 @@
import * as React from 'react';
import {
NavigationAction,
NavigationState,
Router,
} from '@react-navigation/routers';
import NavigationBuilderContext from './NavigationBuilderContext';
import { NavigationAction, NavigationState, Router } from './types';
type Options<Action extends NavigationAction> = {
router: Router<NavigationState, Action>;

View File

@@ -1,6 +1,7 @@
import * as React from 'react';
import { ParamListBase } from '@react-navigation/routers';
import NavigationRouteContext from './NavigationRouteContext';
import { ParamListBase, RouteProp } from './types';
import { RouteProp } from './types';
/**
* Hook to access the route prop of the parent screen anywhere.

View File

@@ -1,5 +1,8 @@
{
"extends": "../../tsconfig",
"references": [
{ "path": "../routers" }
],
"compilerOptions": {
"outDir": "./lib/typescript"
}

View File

@@ -35,12 +35,12 @@
"clean": "del lib"
},
"dependencies": {
"@react-navigation/routers": "^5.0.0",
"color": "^3.1.2",
"react-native-iphone-x-helper": "^1.2.1"
},
"devDependencies": {
"@react-native-community/bob": "^0.9.3",
"@react-navigation/native": "^5.0.0",
"@types/react": "^16.9.19",
"@types/react-native": "^0.60.30",
"del-cli": "^3.0.0",

View File

@@ -3,12 +3,10 @@ import {
createNavigatorFactory,
useNavigationBuilder,
DefaultNavigatorOptions,
} from '@react-navigation/native';
import {
DrawerNavigationState,
DrawerRouterOptions,
DrawerRouter,
} from '@react-navigation/routers';
} from '@react-navigation/native';
import DrawerView from '../views/DrawerView';
import {

View File

@@ -6,8 +6,8 @@ import {
NavigationProp,
Descriptor,
NavigationHelpers,
DrawerNavigationState,
} from '@react-navigation/native';
import { DrawerNavigationState } from '@react-navigation/routers';
import { PanGestureHandler } from 'react-native-gesture-handler';
export type Scene = {

View File

@@ -601,7 +601,10 @@ export default class DrawerView extends React.PureComponent<Props> {
>
{renderSceneContent({ progress: this.progress })}
</View>
<TapGestureHandler onHandlerStateChange={this.handleTapStateChange}>
<TapGestureHandler
enabled={gestureEnabled}
onHandlerStateChange={this.handleTapStateChange}
>
<Overlay progress={this.progress} style={overlayStyle} />
</TapGestureHandler>
</Animated.View>

View File

@@ -1,9 +1,9 @@
import * as React from 'react';
import { CommonActions } from '@react-navigation/native';
import {
CommonActions,
DrawerActions,
DrawerNavigationState,
} from '@react-navigation/routers';
} from '@react-navigation/native';
import DrawerItem from './DrawerItem';
import {
DrawerNavigationHelpers,

View File

@@ -18,8 +18,8 @@ import {
import {
DrawerNavigationState,
DrawerActions,
} from '@react-navigation/routers';
import { useTheme } from '@react-navigation/native';
useTheme,
} from '@react-navigation/native';
import DrawerGestureContext from '../utils/DrawerGestureContext';
import SafeAreaProviderCompat from './SafeAreaProviderCompat';

View File

@@ -2,8 +2,8 @@
"extends": "../../tsconfig",
"references": [
{ "path": "../core" },
{ "path": "../native" },
{ "path": "../routers" }
{ "path": "../routers" },
{ "path": "../native" }
],
"compilerOptions": {
"outDir": "./lib/typescript"

View File

@@ -34,11 +34,10 @@
"prepare": "bob build",
"clean": "del lib"
},
"dependencies": {
"@react-navigation/routers": "^5.0.0"
},
"dependencies": {},
"devDependencies": {
"@react-native-community/bob": "^0.9.3",
"@react-navigation/native": "^5.0.0",
"@types/react": "^16.9.19",
"@types/react-native": "^0.60.30",
"@types/react-native-vector-icons": "^6.4.5",

View File

@@ -3,12 +3,10 @@ import {
useNavigationBuilder,
createNavigatorFactory,
DefaultNavigatorOptions,
} from '@react-navigation/native';
import {
TabRouter,
TabRouterOptions,
TabNavigationState,
} from '@react-navigation/routers';
} from '@react-navigation/native';
import MaterialBottomTabView from '../views/MaterialBottomTabView';
import {

View File

@@ -4,8 +4,8 @@ import {
Descriptor,
NavigationProp,
NavigationHelpers,
TabNavigationState,
} from '@react-navigation/native';
import { TabNavigationState } from '@react-navigation/routers';
export type MaterialBottomTabNavigationEventMap = {
/**

View File

@@ -2,8 +2,12 @@ import * as React from 'react';
import { StyleSheet } from 'react-native';
import { BottomNavigation, DefaultTheme, DarkTheme } from 'react-native-paper';
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
import { Route, useTheme } from '@react-navigation/native';
import { TabNavigationState, TabActions } from '@react-navigation/routers';
import {
Route,
TabNavigationState,
TabActions,
useTheme,
} from '@react-navigation/native';
import {
MaterialBottomTabDescriptorMap,

View File

@@ -2,8 +2,8 @@
"extends": "../../tsconfig",
"references": [
{ "path": "../core" },
{ "path": "../native" },
{ "path": "../routers" }
{ "path": "../routers" },
{ "path": "../native" }
],
"compilerOptions": {
"outDir": "./lib/typescript"

View File

@@ -35,11 +35,11 @@
"clean": "del lib"
},
"dependencies": {
"@react-navigation/routers": "^5.0.0",
"color": "^3.1.2"
},
"devDependencies": {
"@react-native-community/bob": "^0.9.3",
"@react-navigation/native": "^5.0.0",
"@types/react": "^16.9.19",
"@types/react-native": "^0.60.30",
"del-cli": "^3.0.0",

View File

@@ -3,12 +3,10 @@ import {
useNavigationBuilder,
createNavigatorFactory,
DefaultNavigatorOptions,
} from '@react-navigation/native';
import {
TabRouter,
TabRouterOptions,
TabNavigationState,
} from '@react-navigation/routers';
} from '@react-navigation/native';
import MaterialTopTabView from '../views/MaterialTopTabView';
import {
MaterialTopTabNavigationConfig,

View File

@@ -6,8 +6,8 @@ import {
NavigationHelpers,
Route,
NavigationProp,
TabNavigationState,
} from '@react-navigation/native';
import { TabNavigationState } from '@react-navigation/routers';
export type MaterialTopTabNavigationEventMap = {
/**

View File

@@ -1,7 +1,10 @@
import * as React from 'react';
import { TabView, SceneRendererProps } from 'react-native-tab-view';
import { useTheme } from '@react-navigation/native';
import { TabNavigationState, TabActions } from '@react-navigation/routers';
import {
TabNavigationState,
TabActions,
useTheme,
} from '@react-navigation/native';
import MaterialTopTabBar from './MaterialTopTabBar';
import {

View File

@@ -2,8 +2,8 @@
"extends": "../../tsconfig",
"references": [
{ "path": "../core" },
{ "path": "../native" },
{ "path": "../routers" }
{ "path": "../routers" },
{ "path": "../native" }
],
"compilerOptions": {
"outDir": "./lib/typescript"

View File

@@ -29,11 +29,10 @@
"prepare": "bob build",
"clean": "del lib"
},
"dependencies": {
"@react-navigation/routers": "^5.0.0"
},
"dependencies": {},
"devDependencies": {
"@react-native-community/bob": "^0.9.3",
"@react-navigation/native": "^5.0.0",
"del-cli": "^3.0.0",
"react-native-screens": "^2.0.0-beta.2",
"typescript": "^3.7.5"

View File

@@ -3,14 +3,11 @@ import {
createNavigatorFactory,
useNavigationBuilder,
EventArg,
} from '@react-navigation/native';
import {
StackRouter,
StackNavigationState,
StackRouterOptions,
StackActions,
} from '@react-navigation/routers';
} from '@react-navigation/native';
import {
screensEnabled,

View File

@@ -8,11 +8,9 @@ import {
NavigationHelpers,
NavigationProp,
ParamListBase,
} from '@react-navigation/native';
import {
StackNavigationState,
StackRouterOptions,
} from '@react-navigation/routers';
} from '@react-navigation/native';
export type NativeStackNavigationEventMap = {
/**

View File

@@ -1,14 +1,16 @@
import * as React from 'react';
import { View, StyleSheet } from 'react-native';
import { StackNavigationState, StackActions } from '@react-navigation/routers';
import {
ScreenStack,
Screen as ScreenComponent,
ScreenProps,
// eslint-disable-next-line import/no-unresolved
} from 'react-native-screens';
import { useTheme } from '@react-navigation/native';
import {
StackNavigationState,
StackActions,
useTheme,
} from '@react-navigation/native';
import HeaderConfig from './HeaderConfig';
import {
NativeStackNavigationHelpers,

View File

@@ -2,8 +2,8 @@
"extends": "../../tsconfig",
"references": [
{ "path": "../core" },
{ "path": "../native" },
{ "path": "../routers" }
{ "path": "../routers" },
{ "path": "../native" }
],
"compilerOptions": {
"outDir": "./lib/typescript"

View File

@@ -1,7 +1,8 @@
{
"extends": "../../tsconfig",
"references": [
{ "path": "../core" }
{ "path": "../core" },
{ "path": "../routers" }
],
"compilerOptions": {
"outDir": "./lib/typescript"

View File

@@ -30,7 +30,6 @@
"clean": "del lib"
},
"dependencies": {
"@react-navigation/core": "^5.0.0",
"shortid": "^2.2.15"
},
"devDependencies": {

View File

@@ -1,4 +1,4 @@
import { CommonAction, NavigationState, PartialState } from './types';
import { CommonNavigationAction, NavigationState, PartialState } from './types';
/**
* Base router object that can be used when writing custom routers.
@@ -7,7 +7,7 @@ import { CommonAction, NavigationState, PartialState } from './types';
const BaseRouter = {
getStateForAction<State extends NavigationState>(
state: State,
action: CommonAction
action: CommonNavigationAction
): State | PartialState<State> | null {
switch (action.type) {
case 'SET_PARAMS': {
@@ -37,7 +37,7 @@ const BaseRouter = {
}
},
shouldActionChangeFocus(action: CommonAction) {
shouldActionChangeFocus(action: CommonNavigationAction) {
return action.type === 'NAVIGATE';
},
};

View File

@@ -1,5 +1,5 @@
import shortid from 'shortid';
import { CommonAction, Router, PartialState } from '@react-navigation/core';
import { PartialState, CommonNavigationAction, Router } from './types';
import TabRouter, {
TabActions,
TabActionType,
@@ -72,10 +72,10 @@ const closeDrawer = (state: DrawerNavigationState): DrawerNavigationState => {
export default function DrawerRouter(
options: DrawerRouterOptions
): Router<DrawerNavigationState, DrawerActionType | CommonAction> {
): Router<DrawerNavigationState, DrawerActionType | CommonNavigationAction> {
const router = (TabRouter(options) as unknown) as Router<
DrawerNavigationState,
TabActionType | CommonAction
TabActionType | CommonNavigationAction
>;
return {

View File

@@ -1,12 +1,12 @@
import shortid from 'shortid';
import BaseRouter from './BaseRouter';
import {
NavigationState,
CommonAction,
CommonNavigationAction,
Router,
BaseRouter,
DefaultRouterOptions,
Route,
} from '@react-navigation/core';
} from './types';
export type StackActionType =
| {
@@ -58,7 +58,10 @@ export const StackActions = {
};
export default function StackRouter(options: StackRouterOptions) {
const router: Router<StackNavigationState, CommonAction | StackActionType> = {
const router: Router<
StackNavigationState,
CommonNavigationAction | StackActionType
> = {
...BaseRouter,
type: 'stack',

View File

@@ -1,13 +1,13 @@
import shortid from 'shortid';
import BaseRouter from './BaseRouter';
import {
CommonAction,
BaseRouter,
PartialState,
NavigationState,
DefaultRouterOptions,
PartialState,
CommonNavigationAction,
Router,
DefaultRouterOptions,
Route,
} from '@react-navigation/core';
} from './types';
export type TabActionType = {
type: 'JUMP_TO';
@@ -95,7 +95,10 @@ export default function TabRouter({
initialRouteName,
backBehavior = 'history',
}: TabRouterOptions) {
const router: Router<TabNavigationState, TabActionType | CommonAction> = {
const router: Router<
TabNavigationState,
TabActionType | CommonNavigationAction
> = {
...BaseRouter,
type: 'tab',

View File

@@ -0,0 +1,8 @@
import * as CommonActions from '../CommonActions';
it('throws if NAVIGATE is called without key or name', () => {
// @ts-ignore
expect(() => CommonActions.navigate({})).toThrowError(
'While calling navigate with an object as the argument, you need to specify name or key'
);
});

View File

@@ -1,5 +1,9 @@
import { CommonActions } from '@react-navigation/core';
import { DrawerRouter, DrawerActions, DrawerNavigationState } from '../src';
import {
CommonActions,
DrawerRouter,
DrawerActions,
DrawerNavigationState,
} from '..';
jest.mock('shortid', () => () => 'test');

View File

@@ -1,5 +1,4 @@
import { CommonActions } from '@react-navigation/core';
import { StackRouter, StackActions } from '../src';
import { CommonActions, StackRouter, StackActions } from '..';
jest.mock('shortid', () => () => 'test');

View File

@@ -1,5 +1,4 @@
import { CommonActions } from '@react-navigation/core';
import { TabRouter, TabActions, TabNavigationState } from '../src';
import { CommonActions, TabRouter, TabActions, TabNavigationState } from '..';
jest.mock('shortid', () => () => 'test');

View File

@@ -1,3 +1,9 @@
import * as CommonActions from './CommonActions';
export { CommonActions };
export { default as BaseRouter } from './BaseRouter';
export {
default as StackRouter,
StackActions,
@@ -21,3 +27,5 @@ export {
DrawerRouterOptions,
DrawerNavigationState,
} from './DrawerRouter';
export * from './types';

View File

@@ -0,0 +1,192 @@
import * as CommonActions from './CommonActions';
export type CommonNavigationAction = CommonActions.Action;
export type NavigationState = {
/**
* Unique key for the navigation state.
*/
key: string;
/**
* Index of the currently focused route.
*/
index: number;
/**
* List of valid route names as defined in the screen components.
*/
routeNames: string[];
/**
* Alternative entries for history.
*/
history?: unknown[];
/**
* List of rendered routes.
*/
routes: (Route<string> & {
state?: NavigationState | PartialState<NavigationState>;
})[];
/**
* Custom type for the state, whether it's for tab, stack, drawer etc.
* During rehydration, the state will be discarded if type doesn't match with router type.
* It can also be used to detect the type of the navigator we're dealing with.
*/
type: string;
/**
* Whether the navigation state has been rehydrated.
*/
stale: false;
};
export type InitialState = Partial<
Omit<NavigationState, 'stale' | 'routes'>
> & {
routes: (Omit<Route<string>, 'key'> & { state?: InitialState })[];
};
export type PartialState<State extends NavigationState> = Partial<
Omit<State, 'stale' | 'type' | 'key' | 'routes' | 'routeNames'>
> & {
stale?: true;
type?: string;
routes: (Omit<Route<string>, 'key'> & {
key?: string;
state?: InitialState;
})[];
};
export type Route<RouteName extends string> = {
/**
* Unique key for the route.
*/
key: string;
/**
* User-provided name for the route.
*/
name: RouteName;
/**
* Params for the route.
*/
params?: object;
};
export type ParamListBase = Record<string, object | undefined>;
export type NavigationAction = {
/**
* Type of the action (e.g. `NAVIGATE`)
*/
type: string;
/**
* Additional data for the action
*/
payload?: object;
/**
* Key of the route which dispatched this action.
*/
source?: string;
/**
* Key of the navigator which should handle this action.
*/
target?: string;
};
export type ActionCreators<Action extends NavigationAction> = {
[key: string]: (...args: any) => Action;
};
export type DefaultRouterOptions = {
/**
* Name of the route to focus by on initial render.
* If not specified, usually the first route is used.
*/
initialRouteName?: string;
};
export type RouterFactory<
State extends NavigationState,
Action extends NavigationAction,
RouterOptions extends DefaultRouterOptions
> = (options: RouterOptions) => Router<State, Action>;
export type RouterConfigOptions = {
routeNames: string[];
routeParamList: ParamListBase;
};
export type Router<
State extends NavigationState,
Action extends NavigationAction
> = {
/**
* Type of the router. Should match the `type` property in state.
* If the type doesn't match, the state will be discarded during rehydration.
*/
type: State['type'];
/**
* Initialize the navigation state.
*
* @param options.routeNames List of valid route names as defined in the screen components.
* @param options.routeParamsList Object containing params for each route.
*/
getInitialState(options: RouterConfigOptions): State;
/**
* Rehydrate the full navigation state from a given partial state.
*
* @param partialState Navigation state to rehydrate from.
* @param options.routeNames List of valid route names as defined in the screen components.
* @param options.routeParamsList Object containing params for each route.
*/
getRehydratedState(
partialState: PartialState<State> | State,
options: RouterConfigOptions
): State;
/**
* Take the current state and updated list of route names, and return a new state.
*
* @param state State object to update.
* @param options.routeNames New list of route names.
* @param options.routeParamsList Object containing params for each route.
*/
getStateForRouteNamesChange(
state: State,
options: RouterConfigOptions
): State;
/**
* Take the current state and key of a route, and return a new state with the route focused
*
* @param state State object to apply the action on.
* @param key Key of the route to focus.
*/
getStateForRouteFocus(state: State, key: string): State;
/**
* Take the current state and action, and return a new state.
* If the action cannot be handled, return `null`.
*
* @param state State object to apply the action on.
* @param action Action object to apply.
* @param options.routeNames List of valid route names as defined in the screen components.
* @param options.routeParamsList Object containing params for each route.
*/
getStateForAction(
state: State,
action: Action,
options: RouterConfigOptions
): State | PartialState<State> | null;
/**
* Whether the action should also change focus in parent navigator
*
* @param action Action object to check.
*/
shouldActionChangeFocus(action: NavigationAction): boolean;
/**
* Action creators for the router.
*/
actionCreators?: ActionCreators<Action>;
};

View File

@@ -1,8 +1,5 @@
{
"extends": "../../tsconfig",
"references": [
{ "path": "../core" }
],
"compilerOptions": {
"outDir": "./lib/typescript"
}

View File

@@ -34,13 +34,13 @@
"clean": "del lib"
},
"dependencies": {
"@react-navigation/routers": "^5.0.0",
"color": "^3.1.2",
"react-native-iphone-x-helper": "^1.2.1"
},
"devDependencies": {
"@react-native-community/bob": "^0.9.3",
"@react-native-community/masked-view": "^0.1.6",
"@react-navigation/native": "^5.0.0",
"@types/color": "^3.0.1",
"@types/react": "^16.9.19",
"@types/react-native": "^0.60.30",

View File

@@ -4,13 +4,11 @@ import {
createNavigatorFactory,
DefaultNavigatorOptions,
EventArg,
} from '@react-navigation/native';
import {
StackRouter,
StackRouterOptions,
StackNavigationState,
StackActions,
} from '@react-navigation/routers';
} from '@react-navigation/native';
import StackView from '../views/Stack/StackView';
import {
StackNavigationConfig,

View File

@@ -12,8 +12,8 @@ import {
Descriptor,
Route,
NavigationHelpers,
StackNavigationState,
} from '@react-navigation/native';
import { StackNavigationState } from '@react-navigation/routers';
export type StackNavigationEventMap = {
/**

View File

@@ -1,5 +1,5 @@
import * as React from 'react';
import { StackActions } from '@react-navigation/routers';
import { StackActions } from '@react-navigation/native';
import HeaderSegment from './HeaderSegment';
import { StackHeaderProps, StackHeaderTitleProps } from '../../types';

View File

@@ -11,8 +11,7 @@ import {
import { EdgeInsets } from 'react-native-safe-area-context';
// eslint-disable-next-line import/no-unresolved
import { ScreenContainer, Screen, screensEnabled } from 'react-native-screens'; // Import with * as to prevent getters being called
import { Route } from '@react-navigation/native';
import { StackNavigationState } from '@react-navigation/routers';
import { Route, StackNavigationState } from '@react-navigation/native';
import { getDefaultHeaderHeight } from '../Header/HeaderSegment';
import { Props as HeaderContainerProps } from '../Header/HeaderContainer';

View File

@@ -2,8 +2,11 @@ import * as React from 'react';
import { View, Platform, StyleSheet } from 'react-native';
import { SafeAreaConsumer, EdgeInsets } from 'react-native-safe-area-context';
import { GestureHandlerRootView } from 'react-native-gesture-handler';
import { Route } from '@react-navigation/native';
import { StackActions, StackNavigationState } from '@react-navigation/routers';
import {
StackActions,
StackNavigationState,
Route,
} from '@react-navigation/native';
import CardStack from './CardStack';
import KeyboardManager from '../KeyboardManager';

View File

@@ -2,8 +2,8 @@
"extends": "../../tsconfig",
"references": [
{ "path": "../core" },
{ "path": "../native" },
{ "path": "../routers" }
{ "path": "../routers" },
{ "path": "../native" }
],
"compilerOptions": {
"outDir": "./lib/typescript"