Replies: 1 comment 4 replies
-
Hi @luancurti, Thanks for sharing this hook — it's a great start for building reusable collapsible animations with Reanimated! I have a few suggestions that might help improve robustness and flexibility:
Here’s a modified version of your import { useCallback, useEffect, useState } from 'react';
import type { LayoutChangeEvent } from 'react-native';
import {
Easing,
EasingFunction,
cancelAnimation,
useAnimatedStyle,
useSharedValue,
withTiming,
} from 'react-native-reanimated';
type CollapsibleConfig = {
heightOffset?: number;
duration?: number;
easing?: EasingFunction;
isVisible: boolean;
onAnimationEnd?: () => void;
};
export function useCollapsible({
isVisible,
heightOffset = 0,
duration = 300,
easing = Easing.linear,
onAnimationEnd,
}: CollapsibleConfig) {
const [componentHeight, setComponentHeight] = useState(0);
const height = useSharedValue(0);
const opacity = useSharedValue(0);
const onLayout = useCallback((event: LayoutChangeEvent) => {
const { height: layoutHeight } = event.nativeEvent.layout;
setComponentHeight(layoutHeight);
}, []);
useEffect(() => {
height.value = withTiming(
isVisible ? componentHeight + heightOffset : 0,
{ duration, easing },
() => {
if (onAnimationEnd) {
onAnimationEnd();
}
}
);
opacity.value = withTiming(isVisible ? 1 : 0, { duration, easing });
return () => {
cancelAnimation(height);
cancelAnimation(opacity);
};
}, [isVisible, componentHeight, heightOffset, duration, easing, onAnimationEnd]);
const animatedStyle = useAnimatedStyle(() => ({
height: height.value,
opacity: opacity.value,
overflow: 'hidden',
}));
return { animatedStyle, onLayout };
} Let me know what you think — happy to iterate together on this! |
Beta Was this translation helpful? Give feedback.
4 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
Like this example:
Beta Was this translation helpful? Give feedback.
All reactions