UNPKG

@wordpress/components

Version:
138 lines (136 loc) 4.27 kB
/** * External dependencies */ import { NavigationContainer, DefaultTheme } from '@react-navigation/native'; import { createStackNavigator } from '@react-navigation/stack'; import Animated, { Easing, useAnimatedStyle, useSharedValue, withTiming } from 'react-native-reanimated'; /** * WordPress dependencies */ import { useContext, useMemo, useCallback, Children, useRef, cloneElement } from '@wordpress/element'; import { usePreferredColorSchemeStyle } from '@wordpress/compose'; /** * Internal dependencies */ import { BottomSheetNavigationContext, BottomSheetNavigationProvider } from './bottom-sheet-navigation-context'; import { BottomSheetContext } from '../bottom-sheet-context'; import styles from './styles.scss'; import { jsx as _jsx } from "react/jsx-runtime"; const AnimationSpec = { animation: 'timing', config: { duration: 200, easing: Easing.ease } }; const fadeConfig = ({ current }) => { return { cardStyle: { opacity: current.progress } }; }; const options = { transitionSpec: { open: AnimationSpec, close: AnimationSpec }, headerShown: false, gestureEnabled: false, cardStyleInterpolator: fadeConfig, keyboardHandlingEnabled: false }; const HEIGHT_ANIMATION_DURATION = 300; const DEFAULT_HEIGHT = 1; function BottomSheetNavigationContainer({ children, animate, main, theme, style, testID }) { const Stack = useRef(createStackNavigator()).current; const navigationContext = useContext(BottomSheetNavigationContext); const { maxHeight: sheetMaxHeight, isMaxHeightSet: isSheetMaxHeightSet } = useContext(BottomSheetContext); const currentHeight = useSharedValue(navigationContext.currentHeight?.value || DEFAULT_HEIGHT); const backgroundStyle = usePreferredColorSchemeStyle(styles.background, styles.backgroundDark); const defaultTheme = useMemo(() => ({ ...DefaultTheme, colors: { ...DefaultTheme.colors, background: backgroundStyle.backgroundColor } }), [backgroundStyle.backgroundColor]); const _theme = theme || defaultTheme; const setHeight = useCallback(height => { if (height > DEFAULT_HEIGHT && Math.round(height) !== Math.round(currentHeight.value)) { // If max height is set in the bottom sheet, we clamp // the new height using that value. const newHeight = isSheetMaxHeightSet ? Math.min(sheetMaxHeight, height) : height; const shouldAnimate = animate && currentHeight.value !== DEFAULT_HEIGHT; if (shouldAnimate) { currentHeight.value = withTiming(newHeight, { duration: HEIGHT_ANIMATION_DURATION, easing: Easing.out(Easing.cubic) }); } else { currentHeight.value = newHeight; } } }, [animate, currentHeight, isSheetMaxHeightSet, sheetMaxHeight]); const animatedStyles = useAnimatedStyle(() => ({ height: currentHeight.value })); const screens = useMemo(() => { return Children.map(children, child => { let screen = child; const { name, ...otherProps } = child.props; if (!main) { screen = cloneElement(child, { ...child.props, isNested: true }); } return /*#__PURE__*/_jsx(Stack.Screen, { name: name, ...otherProps, children: () => screen }); }); }, [children, main]); return useMemo(() => { return /*#__PURE__*/_jsx(Animated.View, { style: [style, animatedStyles], testID: testID, children: /*#__PURE__*/_jsx(BottomSheetNavigationProvider, { value: { setHeight, currentHeight }, children: main ? /*#__PURE__*/_jsx(NavigationContainer, { theme: _theme, children: /*#__PURE__*/_jsx(Stack.Navigator, { screenOptions: options, detachInactiveScreens: false, children: screens }) }) : /*#__PURE__*/_jsx(Stack.Navigator, { screenOptions: options, detachInactiveScreens: false, children: screens }) }) }); }, [_theme, animatedStyles, currentHeight, main, screens, setHeight, style, testID]); } export default BottomSheetNavigationContainer; //# sourceMappingURL=navigation-container.native.js.map