Skip to content

Instantly share code, notes, and snippets.

@nandorojo
Last active April 1, 2024 18:40
Show Gist options
  • Save nandorojo/8fd2b0f5bd5e75073dcce5a17a6346e4 to your computer and use it in GitHub Desktop.
Save nandorojo/8fd2b0f5bd5e75073dcce5a17a6346e4 to your computer and use it in GitHub Desktop.
Moti Animate Height
import { StyleSheet } from 'react-native'
import Animated, {
useAnimatedStyle,
useSharedValue,
withTiming,
} from 'react-native-reanimated'
import { AnimateHeightProps } from './index.types'
const transition = { duration: 200 } as const
function HeightTransition({
children,
hide = !children,
style,
onHeightDidAnimate,
initialHeight = 0,
}: AnimateHeightProps) {
const measuredHeight = useSharedValue(initialHeight)
const childStyle = useAnimatedStyle(
() => ({
opacity: withTiming(!measuredHeight.value || hide ? 0 : 1, transition),
}),
[hide, measuredHeight]
)
const containerStyle = useAnimatedStyle(() => {
return {
height: withTiming(hide ? 0 : measuredHeight.value, transition, () => {
if (onHeightDidAnimate) {
runOnJS(onHeightDidAnimate)(measuredHeight.value)
}
}),
}
}, [hide, measuredHeight])
return (
<Animated.View style={[styles.hidden, style, containerStyle]}>
<Animated.View
style={[StyleSheet.absoluteFill, styles.autoBottom, childStyle]}
onLayout={({ nativeEvent }) => {
measuredHeight.value = Math.ceil(nativeEvent.layout.height)
}}
>
{children}
</Animated.View>
</Animated.View>
)
}
const styles = StyleSheet.create({
autoBottom: {
bottom: 'auto',
},
hidden: {
overflow: 'hidden',
},
})
export { HeightTransition }
type AnimateHeightProps = {
children?: React.ReactNode
/**
* If `true`, the height will automatically animate to 0. Default: `false`.
*/
hide?: boolean
initialHeight?: number
} & React.ComponentProps<typeof MotiView>
@hzmmohamed
Copy link

@jstheoriginal Thanks a lot for sharing!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment