From ecd68afb46a4c56200748da5e5fb284fa5a839db Mon Sep 17 00:00:00 2001 From: Satyajit Sahoo Date: Mon, 27 Jan 2020 12:59:24 +0100 Subject: [PATCH] feat: add useIsDrawerOpen hook (#299) --- packages/core/src/types.tsx | 6 ++-- packages/drawer/src/index.tsx | 2 ++ packages/drawer/src/utils/useIsDrawerOpen.tsx | 32 +++++++++++++++++++ 3 files changed, 37 insertions(+), 3 deletions(-) create mode 100644 packages/drawer/src/utils/useIsDrawerOpen.tsx diff --git a/packages/core/src/types.tsx b/packages/core/src/types.tsx index c981037e12f7f6..a59278af5aea5e 100644 --- a/packages/core/src/types.tsx +++ b/packages/core/src/types.tsx @@ -212,10 +212,10 @@ export type EventMapBase = Record< { data?: any; canPreventDefault?: boolean } >; -export type EventMapCore = { +export type EventMapCore = { 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 & +} & EventConsumer> & PrivateValueStore; export type RouteProp< diff --git a/packages/drawer/src/index.tsx b/packages/drawer/src/index.tsx index 4f46688e1ac260..054542ba36d09b 100644 --- a/packages/drawer/src/index.tsx +++ b/packages/drawer/src/index.tsx @@ -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 */ diff --git a/packages/drawer/src/utils/useIsDrawerOpen.tsx b/packages/drawer/src/utils/useIsDrawerOpen.tsx new file mode 100644 index 00000000000000..613b34366bacab --- /dev/null +++ b/packages/drawer/src/utils/useIsDrawerOpen.tsx @@ -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; + + // 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; +}