feat: add useIsDrawerOpen hook (#299)

This commit is contained in:
Satyajit Sahoo
2020-01-27 12:59:24 +01:00
committed by Michał Osadnik
parent 5fe140e61b
commit ecd68afb46
3 changed files with 37 additions and 3 deletions

View File

@@ -212,10 +212,10 @@ export type EventMapBase = Record<
{ data?: any; canPreventDefault?: boolean }
>;
export type EventMapCore = {
export type EventMapCore<State extends NavigationState> = {
focus: { data: undefined };
blur: { data: undefined };
state: { data: { state: NavigationState } };
state: { data: { state: State } };
};
export type EventArg<
@@ -458,7 +458,7 @@ export type NavigationProp<
* Note that this method doesn't re-render screen when the result changes. So don't use it in `render`.
*/
dangerouslyGetState(): State;
} & EventConsumer<EventMap & EventMapCore> &
} & EventConsumer<EventMap & EventMapCore<State>> &
PrivateValueStore<ParamList, RouteName, EventMap>;
export type RouteProp<

View File

@@ -17,6 +17,8 @@ export { default as DrawerContentScrollView } from './views/DrawerContentScrollV
*/
export { default as DrawerGestureContext } from './utils/DrawerGestureContext';
export { default as useIsDrawerOpen } from './utils/useIsDrawerOpen';
/**
* Types
*/

View File

@@ -0,0 +1,32 @@
import * as React from 'react';
import { useNavigation, ParamListBase } from '@react-navigation/native';
import { DrawerNavigationProp } from '../types';
/**
* Hook to detect if the drawer is open in a parent navigator.
*/
export default function useIsDrawerOpen() {
const navigation = useNavigation();
let drawer = navigation as DrawerNavigationProp<ParamListBase>;
// The screen might be inside another navigator such as stack nested in drawer
// We need to find the closest drawer navigator and add the listener there
while (drawer && drawer.dangerouslyGetState().type !== 'drawer') {
drawer = drawer.dangerouslyGetParent();
}
const [isDrawerOpen, setIsDrawerOpen] = React.useState(() =>
drawer ? drawer.dangerouslyGetState().isDrawerOpen : false
);
React.useEffect(() => {
const unsubscribe = drawer.addListener('state', e => {
setIsDrawerOpen(e.data.state.isDrawerOpen);
});
return unsubscribe;
}, [drawer]);
return isDrawerOpen;
}