import type { ReactElement, ReactNode } from 'react'; import React, { useEffect, useRef, useState } from 'react'; import { Animated, Dimensions, Easing } from 'react-native'; import DragableDrawer from './DragableDrawer'; import { StyledBackdrop, StyledContainer, StyledDrawerContainer, } from './StyledDrawer'; const BACKDROP_OPACITY = 0.56; interface DrawerProps { /** * Drawer's visibility. */ visible: boolean; /** * Drawer's content. */ children?: ReactNode; /** * Enable the drawer's backdrop. */ hasBackdrop?: boolean; /** * Callback when the drawer is dismissed by interacting outside of the drawer. */ onDismiss?: () => void; /** * Testing id of the component. * */ testID?: string; } const Drawer = ({ visible, children, hasBackdrop = true, onDismiss, testID, }: DrawerProps): ReactElement => { const animatedValue = useRef(new Animated.Value(visible ? 1 : 0)).current; const [height, setHeight] = useState(Dimensions.get('window').height); const enableShadow = visible && hasBackdrop; const interpolateTranslateY = animatedValue.interpolate({ inputRange: [0, 1], outputRange: [-height, 0], }); const interpolateBackdropOpacity = hasBackdrop ? animatedValue.interpolate({ inputRange: [0, 1], outputRange: [0, BACKDROP_OPACITY], }) : 0; useEffect(() => { const animation = Animated.timing(animatedValue, { toValue: visible ? 1 : 0, easing: Easing.inOut(Easing.cubic), useNativeDriver: true, }); animation.start(); return () => animation.stop(); }, [visible]); return ( setHeight(nativeEvent.layout.height)} style={{ transform: [{ translateY: interpolateTranslateY }], }} > {children} ); }; export default Object.assign(Drawer, { Dragable: DragableDrawer, });