diff --git a/native/tooltip/nux-tips-overlay.react.js b/native/tooltip/nux-tips-overlay.react.js --- a/native/tooltip/nux-tips-overlay.react.js +++ b/native/tooltip/nux-tips-overlay.react.js @@ -3,7 +3,7 @@ import invariant from 'invariant'; import * as React from 'react'; import { View, TouchableWithoutFeedback, Platform, Text } from 'react-native'; -import Animated from 'react-native-reanimated'; +import Animated, { withTiming } from 'react-native-reanimated'; import type { AppNavigationProp } from '../navigation/app-navigator.react.js'; import { OverlayContext } from '../navigation/overlay-context.js'; @@ -23,6 +23,8 @@ const { Value, Extrapolate, add, multiply, interpolateNode } = Animated; +const animationDuration = 150; + const unboundStyles = { backdrop: { backgroundColor: 'black', @@ -78,6 +80,20 @@ const tipHeight: number = 30; const margin: number = 20; +function opacityEnteringAnimation() { + 'worklet'; + + return { + animations: { + opacity: withTiming(0.7, { duration: animationDuration }), + transform: [{}], + }, + initialValues: { + opacity: 0, + }, + }; +} + function createNUXTipsOverlay( ButtonComponent: React.ComponentType, getTipText: () => string, @@ -86,6 +102,7 @@ const dimensions = useSelector(state => state.dimensions); const overlayContext = React.useContext(OverlayContext); invariant(overlayContext, 'NUXTipsOverlay should have OverlayContext'); + const { animationCallback } = overlayContext; const position = React.useMemo(() => new Animated.Value(1), []); @@ -108,18 +125,6 @@ }; }, [dimensions.height, route.params, styles.contentContainer]); - const opacityStyle = React.useMemo(() => { - const backdropOpacity = interpolateNode(position, { - inputRange: [0, 1], - outputRange: [0, 0.7], - extrapolate: Extrapolate.CLAMP, - }); - return { - ...styles.backdrop, - opacity: backdropOpacity, - }; - }, [position, styles.backdrop]); - const { initialCoordinates, verticalBounds } = props.route.params; const buttonStyle = React.useMemo(() => { @@ -248,10 +253,29 @@ const tipText = getTipText(); + const opacityExitingAnimation = React.useCallback(() => { + 'worklet'; + + return { + animations: { + opacity: withTiming(0, { duration: animationDuration }), + }, + initialValues: { + opacity: 0.7, + }, + callback: animationCallback, + }; + }, [animationCallback]); + return ( - + @@ -270,7 +294,17 @@ ); } - return React.memo(NUXTipsOverlay); + + function NUXTipsOverlayWrapper(props: NUXTipsOverlayProps) { + const overlayContext = React.useContext(OverlayContext); + invariant(overlayContext, 'NUXTipsOverlay should have OverlayContext'); + + const { renderChild } = overlayContext; + + return renderChild ? : null; + } + + return React.memo(NUXTipsOverlayWrapper); } export { createNUXTipsOverlay };