Skip to content

Commit

Permalink
feat: add native container with back button integration (react-naviga…
Browse files Browse the repository at this point in the history
  • Loading branch information
osdnk authored and satya164 committed Aug 14, 2019
1 parent 4a3db4e commit b7735af
Show file tree
Hide file tree
Showing 12 changed files with 94 additions and 7 deletions.
1 change: 1 addition & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"react": { "version": "16" },
"import/core-modules": [
"@navigation-ex/core",
"@navigation-ex/native",
"@navigation-ex/routers",
"@navigation-ex/stack",
"@navigation-ex/drawer",
Expand Down
15 changes: 14 additions & 1 deletion packages/core/src/NavigationContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,19 @@ const Container = React.forwardRef(function NavigationContainer(
listeners[0](navigation => navigation.dispatch(action));
};

const canGoBack = () => {
const { result, handled } = listeners[0](navigation =>
navigation.canGoBack()
);

if (handled) {
return result;
} else {
return false;
}
};

React.useImperativeHandle(ref, () => ({
dispatch,
...(Object.keys(BaseActions) as Array<keyof typeof BaseActions>).reduce<
any
>((acc, name) => {
Expand All @@ -114,6 +125,8 @@ const Container = React.forwardRef(function NavigationContainer(
);
return acc;
}, {}),
dispatch,
canGoBack,
}));

const navigationStateRef = React.useRef<State>();
Expand Down
3 changes: 2 additions & 1 deletion packages/core/src/useDescriptors.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,13 @@ export default function useDescriptors<
getState,
setState,
addActionListener,
addFocusedListener,
onRouteFocus,
router,
emitter,
addFocusedListener,
}: Options<ScreenOptions>) {
const [options, setOptions] = React.useState<{ [key: string]: object }>({});

const context = React.useMemo(
() => ({
navigation,
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/useNavigationBuilder.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -243,9 +243,9 @@ export default function useNavigationBuilder<
setState,
onRouteFocus,
addActionListener,
addFocusedListener,
router,
emitter,
addFocusedListener,
});

return {
Expand Down
3 changes: 1 addition & 2 deletions packages/core/src/useNavigationHelpers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,14 @@ export default function useNavigationHelpers<
const { performTransaction } = React.useContext(NavigationStateContext);

return React.useMemo(() => {
const dispatch = (action: Action | ((state: State) => State)) => {
const dispatch = (action: Action | ((state: State) => State)) =>
performTransaction(() => {
if (typeof action === 'function') {
setState(action(getState()));
} else {
onAction(action);
}
});
};

const actions = {
...router.actionCreators,
Expand Down
1 change: 1 addition & 0 deletions packages/example/metro.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ module.exports = {
'react-native-paper',
'react-native-tab-view',
'shortid',
'use-subscription',
],
},

Expand Down
3 changes: 2 additions & 1 deletion packages/example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@
"react-native-tab-view": "2.7.1",
"react-native-web": "^0.11.4",
"scheduler": "^0.14.0",
"shortid": "^2.2.14"
"shortid": "^2.2.14",
"use-subscription": "^1.0.0"
},
"devDependencies": {
"@babel/core": "^7.5.5",
Expand Down
13 changes: 12 additions & 1 deletion packages/example/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,13 @@ import * as React from 'react';
import { ScrollView, AsyncStorage, YellowBox } from 'react-native';
import { Appbar, List } from 'react-native-paper';
import { Asset } from 'expo-asset';
import { NavigationContainer, InitialState } from '@navigation-ex/core';
import {
NavigationContainer,
InitialState,
NavigationHelpers,
ParamListBase,
} from '@navigation-ex/core';
import { useNativeIntegration } from '@navigation-ex/native';
import {
createDrawerNavigator,
DrawerNavigationProp,
Expand Down Expand Up @@ -51,6 +57,10 @@ const PERSISTENCE_KEY = 'NAVIGATION_STATE';
Asset.loadAsync(StackAssets);

export default function App() {
const containerRef = React.useRef<NavigationHelpers<ParamListBase>>(null);

useNativeIntegration(containerRef);

const [isReady, setIsReady] = React.useState(false);
const [initialState, setInitialState] = React.useState<
InitialState | undefined
Expand Down Expand Up @@ -79,6 +89,7 @@ export default function App() {

return (
<NavigationContainer
ref={containerRef}
initialState={initialState}
onStateChange={state =>
AsyncStorage.setItem(PERSISTENCE_KEY, JSON.stringify(state))
Expand Down
19 changes: 19 additions & 0 deletions packages/native/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"name": "@navigation-ex/native",
"version": "0.0.1",
"main": "src/index",
"license": "MIT",
"dependencies": {
"@navigation-ex/core": "^0.0.1"
},
"devDependencies": {
"@types/react": "^16.8.24",
"@types/react-native": "^0.60.2",
"react": "16.8.3",
"react-native": "^0.59.8"
},
"peerDependencies": {
"react": "*",
"react-native": "*"
}
}
2 changes: 2 additions & 0 deletions packages/native/src/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { default as useBackButton } from './useBackButton';
export { default as useNativeIntegration } from './useNativeIntegration';
30 changes: 30 additions & 0 deletions packages/native/src/useBackButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import * as React from 'react';
import { NavigationHelpers, ParamListBase } from '@navigation-ex/core';
import { BackHandler } from 'react-native';

export default function useBackButton(
ref: React.RefObject<NavigationHelpers<ParamListBase>>
) {
React.useEffect(() => {
const subscription = BackHandler.addEventListener(
'hardwareBackPress',
() => {
if (ref.current == null) {
return false;
}

const navigation = ref.current;

if (navigation.canGoBack()) {
navigation.goBack();

return true;
}

return false;
}
);

return () => subscription.remove();
}, [ref]);
}
9 changes: 9 additions & 0 deletions packages/native/src/useNativeIntegration.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import * as React from 'react';
import { NavigationHelpers, ParamListBase } from '@navigation-ex/core';
import useBackButton from './useBackButton';

export default function useNativeIntegration(
ref: React.RefObject<NavigationHelpers<ParamListBase>>
) {
useBackButton(ref);
}

0 comments on commit b7735af

Please sign in to comment.