Last active
June 6, 2024 13:23
-
-
Save kibolho/4bf58d7260b6be17d6856147de6e340f to your computer and use it in GitHub Desktop.
useAnimatedCollapse
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import Animated, { SharedValue, interpolate, useAnimatedStyle } from 'react-native-reanimated'; | |
| import CaretUp from '~/assets/images/icons/CaretUp'; | |
| export const CaretAnimated = ({ | |
| isCollapsible, | |
| hidden, | |
| }: { | |
| isCollapsible: SharedValue<number>; | |
| hidden?: boolean; | |
| }) => { | |
| const rotationAnimatedStyle = useAnimatedStyle(() => { | |
| const rotation = interpolate(isCollapsible.value, [1, 0], [0, -180]); | |
| return { transform: [{ rotate: `${rotation}deg` }] }; | |
| }); | |
| if (hidden) { | |
| return null; | |
| } | |
| return ( | |
| <Animated.View style={rotationAnimatedStyle}> | |
| <CaretUp /> | |
| </Animated.View> | |
| ); | |
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| export const Home = () => { | |
| const { toggleButton, bodyHeight, setBodySectionHeight, isCollapsible } = useAnimatedCollapse({ | |
| startExpanded: true, | |
| }); | |
| return ( | |
| <Box style={styles.container}> | |
| <PressableCustom onPress={toggleButton} hitSlop={16} style={styles.headerContainer}> | |
| <Box style={styles.headerBody}> | |
| Title | |
| </Box> | |
| <CaretAnimated isCollapsible={isCollapsible} hidden={!!exampleCard} /> | |
| </PressableCustom> | |
| {shouldRenderContent && ( | |
| <AnimatedWrapper bodyHeight={bodyHeight} setBodySectionHeight={setBodySectionHeight}> | |
| <Box style={styles.contentContainer}> | |
| /// body | |
| </Box> | |
| </AnimatedWrapper> | |
| )} | |
| </Box> | |
| ); | |
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { useState } from 'react'; | |
| import { | |
| Easing, | |
| interpolate, | |
| useAnimatedStyle, | |
| useSharedValue, | |
| withTiming, | |
| } from 'react-native-reanimated'; | |
| export const useAnimatedCollapse = ({ | |
| isNotExpandable, | |
| startExpanded, | |
| onClose, | |
| }: { | |
| isNotExpandable?: boolean; | |
| startExpanded?: boolean; | |
| onClose?: () => void; | |
| }) => { | |
| // start animation logic | |
| const sharedValue = useSharedValue(isNotExpandable || startExpanded ? 1 : 0); | |
| const [bodySectionHeight, setBodySectionHeight] = useState(0); | |
| const bodyHeight = useAnimatedStyle(() => ({ | |
| height: interpolate(sharedValue.value, [0, 1], [0, bodySectionHeight]), | |
| })); | |
| const toggleButton = () => { | |
| if (isNotExpandable) { | |
| return; | |
| } | |
| if (sharedValue.value === 0) { | |
| sharedValue.value = withTiming(1, { | |
| duration: 300, | |
| easing: Easing.bezier(0.4, 0.0, 0.2, 1), | |
| }); | |
| } else { | |
| sharedValue.value = withTiming(0, { | |
| duration: 300, | |
| easing: Easing.bezier(0.4, 0.0, 0.2, 1), | |
| }); | |
| onClose?.(); | |
| } | |
| }; | |
| // end animation logic | |
| return { toggleButton, bodyHeight, setBodySectionHeight, isCollapsible: sharedValue }; | |
| }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment