UNPKG

react-native-trays

Version:

Production-grade, Family inspired, React Native Tray System library

120 lines (118 loc) 3.96 kB
"use strict"; /** * TrayRenderer.tsx * * Renders a single tray component with animation and keyboard adjustment support. * Handles tray position, animation, and keyboard-aware behavior for tray UI. */ import React, { useEffect } from 'react'; import { View, Platform, Keyboard, StyleSheet } from 'react-native'; import Animated, { useAnimatedStyle, useSharedValue, withTiming, Easing, LinearTransition, SlideInDown, SlideOutDown, FadeInDown, FadeOutDown } from 'react-native-reanimated'; /** * Props for TrayRenderer component. * @property trayKey - Unique key for the tray instance. * @property trayProps - Props to pass to the tray component. * @property config - Tray stack configuration. * @property TrayComponent - The tray component to render. * @property insets - Safe area insets for proper positioning. */ import { jsx as _jsx } from "react/jsx-runtime"; /** * TrayRenderer * * Renders the given tray component with animation and keyboard-aware adjustments. * Handles tray position, entry/exit animations, and safe area insets. */ export const TrayRenderer = ({ trayKey, trayProps, config, TrayComponent, insets }) => { const trayBottom = useSharedValue(insets.bottom); useEffect(() => { if (!config.adjustForKeyboard) return; const handleKeyboardShow = e => { trayBottom.value = withTiming(e.endCoordinates.height + 20, { duration: Platform.OS === 'ios' ? 60 : 250, easing: Easing.out(Easing.ease) }); }; const handleKeyboardHide = () => { trayBottom.value = withTiming(insets.bottom, { duration: Platform.OS === 'ios' ? 90 : 200, easing: Easing.out(Easing.ease) }); }; const showSub = Platform.OS === 'ios' ? Keyboard.addListener('keyboardWillShow', handleKeyboardShow) : Keyboard.addListener('keyboardDidShow', handleKeyboardShow); const hideSub = Platform.OS === 'ios' ? Keyboard.addListener('keyboardWillHide', handleKeyboardHide) : Keyboard.addListener('keyboardDidHide', handleKeyboardHide); return () => { showSub.remove(); hideSub.remove(); }; }, [config.adjustForKeyboard, insets.bottom, trayBottom]); const trayAnimatedStyle = useAnimatedStyle(() => config.stickToTop ? { top: insets.top + (typeof config.trayStyles?.top === 'number' ? config.trayStyles?.top : 0) } : { bottom: trayBottom.value + (typeof config.trayStyles?.bottom === 'number' ? config.trayStyles?.bottom : 0) }, [config.trayStyles]); const { enteringAnimation = SlideInDown, exitingAnimation = SlideOutDown, horizontalSpacing = 20 } = config; return /*#__PURE__*/_jsx(Animated.View, { style: [styles.tray, { backgroundColor: config.customTheming ? undefined : '#fff', shadowColor: config.customTheming ? undefined : '#000', left: insets.left + horizontalSpacing, right: insets.right + horizontalSpacing }, config.trayStyles, trayAnimatedStyle], layout: LinearTransition.easing(Easing.out(Easing.ease)).duration(150), entering: enteringAnimation, exiting: exitingAnimation, children: /*#__PURE__*/_jsx(View, { style: styles.content, children: /*#__PURE__*/_jsx(Animated.View, { entering: FadeInDown.duration(180), exiting: FadeOutDown.duration(120), children: /*#__PURE__*/_jsx(TrayComponent, { ...(trayProps ?? {}) }) }, trayKey) }) }); }; const styles = StyleSheet.create({ tray: { position: 'absolute', borderRadius: 30, shadowOffset: { width: 0, height: 5 }, shadowOpacity: 0.25, shadowRadius: 40, elevation: 10, overflow: 'hidden', zIndex: 999 }, content: { position: 'relative', flex: 1 }, closeBtnWrapper: { position: 'absolute', zIndex: 1, top: 20, right: 20, overflow: 'hidden' }, closeBtn: { width: 30, height: 30, zIndex: 2 } }); //# sourceMappingURL=TrayRenderer.js.map