Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | 1x 4x 4x 4x 4x 4x 4x 3x 3x 3x 3x 2x 2x 2x 2x 2x 2x 2x 1x 1x 1x 1x 1x 1x 1x 4x | import { useEffect, useRef, useState } from 'react';
import {
Easing,
runOnJS,
useAnimatedStyle,
useSharedValue,
withTiming,
} from 'react-native-reanimated';
import { InteractionManager, Keyboard, TextInput } from 'react-native';
type UseSearchOverlayAnimationParams = {
isSearchOpen: boolean;
};
export const useSearchOverlayAnimation = ({
isSearchOpen,
}: UseSearchOverlayAnimationParams) => {
const searchInputRef = useRef<TextInput>(null);
const overlayOpacity = useSharedValue(0);
const overlayTranslateY = useSharedValue(8);
const [isSearchInteractive, setIsSearchInteractive] = useState(false);
const searchOverlayAnimatedStyle = useAnimatedStyle(() => ({
opacity: overlayOpacity.value,
transform: [{ translateY: overlayTranslateY.value }],
}));
useEffect(() => {
const openDuration = 220;
const closeDuration = 180;
const easing = Easing.out(Easing.cubic);
let focusTimeout: ReturnType<typeof setTimeout> | undefined;
if (isSearchOpen) {
setIsSearchInteractive(true);
overlayOpacity.value = withTiming(1, { duration: openDuration, easing });
overlayTranslateY.value = withTiming(0, {
duration: openDuration,
easing,
});
focusTimeout = setTimeout(() => {
InteractionManager.runAfterInteractions(() => {
searchInputRef.current?.focus();
});
}, 120);
return () => {
Eif (focusTimeout) {
clearTimeout(focusTimeout);
}
};
}
Keyboard.dismiss();
overlayOpacity.value = withTiming(0, { duration: closeDuration, easing });
overlayTranslateY.value = withTiming(
8,
{ duration: closeDuration, easing },
finished => {
Eif (finished) {
runOnJS(setIsSearchInteractive)(false);
}
},
);
return () => {
Iif (focusTimeout) {
clearTimeout(focusTimeout);
}
};
}, [isSearchOpen, overlayOpacity, overlayTranslateY]);
return {
searchInputRef,
isSearchInteractive,
shouldHideBaseContent: isSearchOpen || isSearchInteractive,
searchOverlayAnimatedStyle,
};
};
|