Skip to content
This repository has been archived by the owner on Feb 8, 2020. It is now read-only.

feat: integrate reanimated based stack #42

Merged
merged 1 commit into from
Aug 6, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@
"prettier": "^1.18.2",
"typescript": "^3.5.1"
},
"resolutions": {
"react": "16.8.3",
"react-native": "https://github.com/expo/react-native/archive/sdk-34.0.0.tar.gz",
"react-native-safe-area-view": "0.14.6"
},
"husky": {
"hooks": {
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS",
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/BaseActions.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { PartialState, NavigationState, TargetRoute } from './types';

export type Action =
| { type: 'GO_BACK' }
| { type: 'GO_BACK'; source?: string }
| {
type: 'NAVIGATE';
payload:
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/NavigationContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as React from 'react';
import { NavigationProp, ParamListBase } from './types';

const NavigationContext = React.createContext<
NavigationProp<ParamListBase> | undefined
NavigationProp<ParamListBase, string, any, any> | undefined
>(undefined);

export default NavigationContext;
11 changes: 7 additions & 4 deletions packages/core/src/SceneView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,24 @@ import {
RouteConfig,
} from './types';

type Props<ScreenOptions extends object> = {
type Props<State extends NavigationState, ScreenOptions extends object> = {
screen: RouteConfig<ParamListBase, string, ScreenOptions>;
navigation: NavigationProp<ParamListBase>;
navigation: NavigationProp<ParamListBase, string, State, ScreenOptions>;
route: Route<string> & { state?: NavigationState };
getState: () => NavigationState;
setState: (state: NavigationState) => void;
};

export default function SceneView<ScreenOptions extends object>({
export default function SceneView<
State extends NavigationState,
ScreenOptions extends object
>({
screen,
route,
navigation,
getState,
setState,
}: Props<ScreenOptions>) {
}: Props<State, ScreenOptions>) {
const { performTransaction } = React.useContext(NavigationStateContext);

const getCurrentState = React.useCallback(() => {
Expand Down
21 changes: 19 additions & 2 deletions packages/core/src/types.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,13 @@ export type CompositeNavigationProp<
A extends NavigationProp<any, any, any, any, infer E> ? E : {}
>;

export type Descriptor<ScreenOptions extends object> = {
export type Descriptor<
ParamList extends ParamListBase,
RouteName extends keyof ParamList = string,
State extends NavigationState = NavigationState,
ScreenOptions extends object = {},
EventMap extends { [key: string]: any } = {}
> = {
/**
* Render the component associated with this route.
*/
Expand All @@ -359,6 +365,17 @@ export type Descriptor<ScreenOptions extends object> = {
* Options for the route.
*/
options: ScreenOptions;

/**
* Navigation object for the screen
*/
navigation: NavigationProp<
ParamList,
RouteName,
State,
ScreenOptions,
EventMap
>;
};

export type RouteConfig<
Expand All @@ -378,7 +395,7 @@ export type RouteConfig<
| ScreenOptions
| ((props: {
route: RouteProp<ParamList, RouteName>;
navigation: NavigationHelpersCommon<ParamList>;
navigation: any;
}) => ScreenOptions);

/**
Expand Down
12 changes: 9 additions & 3 deletions packages/core/src/useDescriptors.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,10 @@ type Options<ScreenOptions extends object> = {
emitter: NavigationEventEmitter;
};

export default function useDescriptors<ScreenOptions extends object>({
export default function useDescriptors<
State extends NavigationState,
ScreenOptions extends object
>({
state,
screens,
navigation,
Expand Down Expand Up @@ -61,7 +64,7 @@ export default function useDescriptors<ScreenOptions extends object>({
]
);

const navigations = useNavigationCache({
const navigations = useNavigationCache<State, ScreenOptions>({
state,
getState,
navigation,
Expand Down Expand Up @@ -97,9 +100,12 @@ export default function useDescriptors<ScreenOptions extends object>({
})),
...options[route.key],
},
navigation: navigations[route.key],
};
return acc;
},
{} as { [key: string]: Descriptor<ScreenOptions> }
{} as {
[key: string]: Descriptor<ParamListBase, string, State, ScreenOptions>;
}
);
}
2 changes: 1 addition & 1 deletion packages/core/src/useNavigationBuilder.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ export default function useNavigationBuilder<
actionCreators: router.actionCreators,
});

const descriptors = useDescriptors<ScreenOptions>({
const descriptors = useDescriptors<State, ScreenOptions>({
state,
screens,
navigation,
Expand Down
109 changes: 56 additions & 53 deletions packages/core/src/useNavigationCache.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,66 +18,69 @@ type Options = {
emitter: NavigationEventEmitter;
};

type NavigationCache = { [key: string]: NavigationProp<ParamListBase> };
type NavigationCache<
State extends NavigationState,
ScreenOptions extends object
> = {
[key: string]: NavigationProp<ParamListBase, string, State, ScreenOptions>;
};

export default function useNavigationCache({
state,
getState,
navigation,
setOptions,
emitter,
}: Options) {
// eslint-disable-next-line react-hooks/exhaustive-deps
const cache = React.useMemo(() => ({ current: {} as NavigationCache }), [
getState,
navigation,
setOptions,
emitter,
]);
export default function useNavigationCache<
State extends NavigationState,
ScreenOptions extends object
>({ state, getState, navigation, setOptions, emitter }: Options) {
const cache = React.useMemo(
() => ({ current: {} as NavigationCache<State, ScreenOptions> }),
// eslint-disable-next-line react-hooks/exhaustive-deps
[getState, navigation, setOptions, emitter]
);

cache.current = state.routes.reduce<NavigationCache>((acc, route, index) => {
const previous = cache.current[route.key];
const isFirst = route.key === state.routes[0].key;
cache.current = state.routes.reduce<NavigationCache<State, ScreenOptions>>(
(acc, route, index) => {
const previous = cache.current[route.key];
const isFirst = route.key === state.routes[0].key;

if (previous && previous.isFirstRouteInParent() === isFirst) {
acc[route.key] = previous;
} else {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { emit, ...rest } = navigation;
if (previous && previous.isFirstRouteInParent() === isFirst) {
acc[route.key] = previous;
} else {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { emit, ...rest } = navigation;

acc[route.key] = {
...rest,
...emitter.create(route.key),
dispatch: (
action:
| NavigationAction
| ((state: NavigationState) => NavigationState)
) =>
navigation.dispatch(
typeof action === 'object' && action != null
? { source: route.key, ...action }
: action
),
setOptions: (options: object) =>
setOptions(o => ({
...o,
[route.key]: { ...o[route.key], ...options },
})),
isFocused: () => {
const state = getState();
acc[route.key] = {
...rest,
...emitter.create(route.key),
dispatch: (
action:
| NavigationAction
| ((state: NavigationState) => NavigationState)
) =>
navigation.dispatch(
typeof action === 'object' && action != null
? { source: route.key, ...action }
: action
),
setOptions: (options: object) =>
setOptions(o => ({
...o,
[route.key]: { ...o[route.key], ...options },
})),
isFocused: () => {
const state = getState();

if (index !== state.index) {
return false;
}
if (index !== state.index) {
return false;
}

return navigation ? navigation.isFocused() : true;
},
isFirstRouteInParent: () => isFirst,
} as NavigationProp<ParamListBase>;
}
return navigation ? navigation.isFocused() : true;
},
isFirstRouteInParent: () => isFirst,
} as NavigationProp<ParamListBase, string, State, ScreenOptions>;
}

return acc;
}, {});
return acc;
},
{}
);

return cache.current;
}
2 changes: 2 additions & 0 deletions packages/example/metro.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,13 @@ module.exports = {

providesModuleNodeModules: [
'@babel/runtime',
'@react-native-community/masked-view',
'react',
'react-native',
'react-native-gesture-handler',
'react-native-reanimated',
'react-native-safe-area-view',
'react-native-screens',
'react-native-tab-view',
'shortid',
],
Expand Down
7 changes: 2 additions & 5 deletions packages/example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,15 @@
"eject": "expo eject"
},
"dependencies": {
"@react-native-community/masked-view": "^0.1.1",
"expo": "^34.0.1",
"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-screens": "1.0.0-alpha.22",
"react-native-tab-view": "2.7.1",
"react-native-web": "^0.11.4",
"scheduler": "^0.14.0",
Expand All @@ -36,10 +38,5 @@
"@types/react-native": "^0.57.65",
"babel-preset-expo": "^6.0.0",
"expo-cli": "^3.0.6"
},
"resolutions": {
"react": "16.8.3",
"react-dom": "^16.8.3",
"react-native-safe-area-view": "0.14.6"
}
}
15 changes: 8 additions & 7 deletions packages/material-top-tabs/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ type Props = TabRouterOptions &
children: React.ReactNode;
};

export type TabNavigationOptions = {
export type MaterialTopTabNavigationOptions = {
/**
* Title text for the screen.
*/
Expand All @@ -36,7 +36,7 @@ export type MaterialTopTabNavigationProp<
ParamList,
RouteName,
TabNavigationState,
TabNavigationOptions
MaterialTopTabNavigationOptions
> & {
/**
* Jump to an existing tab.
Expand All @@ -51,15 +51,15 @@ export type MaterialTopTabNavigationProp<
): void;
};

export function TabNavigator({
function TabNavigator({
initialRouteName,
backBehavior,
children,
...rest
}: Props) {
const { state, descriptors, navigation } = useNavigationBuilder<
TabNavigationState,
TabNavigationOptions,
MaterialTopTabNavigationOptions,
TabRouterOptions
>(TabRouter, {
initialRouteName,
Expand All @@ -85,6 +85,7 @@ export function TabNavigator({
);
}

export default createNavigator<TabNavigationOptions, typeof TabNavigator>(
TabNavigator
);
export default createNavigator<
MaterialTopTabNavigationOptions,
typeof TabNavigator
>(TabNavigator);
Loading