A cross-platform smooth expand/collapse animation helpers for React Native.
- Example mobile app.
- Example web app.
- Checkout the example/ directory for source code.
- Smooth animations
- Headless UI
- Cross-platform (iOS, Android, Web)
- Highly customizable
- Fully typed with TypeScript
demo.mov
Open a Terminal in the project root and run:
npm install reanimated-collapsible-helpers
or
yarn add reanimated-collapsible-helpers
Now we need to install react-native-reanimated
.
If you are using Expo, to ensure that you get the compatible versions of the libraries, run:
expo install react-native-reanimated
If you are not using Expo, run the following:
npm install react-native-reanimated
or
yarn add react-native-reanimated
If you are using Expo, you are done. Otherwise, continue to the next steps.
Next, we need to link these libraries. The steps depends on your React Native version:
-
React Native 0.60 and higher
On newer versions of React Native, linking is automatic.
To complete the linking on iOS, make sure you have Cocoapods installed. Then run:
cd ios pod install cd ..
-
React Native 0.59 and lower
If you're on an older React Native version, you need to manually link the dependencies. To do that, run:
react-native link react-native-reanimated
We're done! Now you can build and run the app on your device/simulator.
import * as React from 'react';
import { Text, View, StyleSheet, TouchableOpacity } from 'react-native';
import {
useCollapsible,
AnimatedSection,
} from 'reanimated-collapsible-helpers';
export default function App() {
const { animatedHeight, height, onPress, onLayout, state } = useCollapsible();
return (
<View style={styles.background}>
<View style={styles.overflow}>
<TouchableOpacity onPress={onPress} style={styles.button}>
<Text style={styles.buttonText}>
{state === 'expanded' ? 'Collapse' : 'Expand'}
</Text>
</TouchableOpacity>
<AnimatedSection
animatedHeight={animatedHeight}
onLayout={onLayout}
state={state}
>
<View style={styles.textContainer}>
<Text>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean
quis erat suscipit, mollis nibh ut, venenatis lectus. Orci varius
natoque penatibus et magnis dis parturient montes, nascetur
ridiculus mus.
</Text>
</View>
</AnimatedSection>
</View>
</View>
);
}
const styles = StyleSheet.create({
background: {
flex: 1,
backgroundColor: '#efefef',
padding: 20,
},
overflow: {
overflow: 'hidden',
backgroundColor: 'white',
borderRadius: 6,
},
button: {
padding: 10,
textAlign: 'center',
},
buttonText: {
fontSize: 20,
},
textContainer: {
padding: 15,
},
});
The package exports one hook and one component:
useCollapsible
hookAnimatedSection
component
A hook responsible for managing state, animation and providing helper functions.
Usage looks like this:
const { animatedHeight, height, onPress, onLayout, state } = useCollapsible();
It accepts one argument config
- an object containing following properties:
duration
: A number representing an expand/collapse animation duration (Optional, defaults to250ms
).easing
: An easing function used by the animation (Optional, defaults toEasing.out(Easing.ease)
).
Hook returns an object with following properties:
state
: An enum representing a state of the animation -expanded
orcollapsed
.height
: A number representing full height of the collapsible section. Handy for defining upper bounds of the custom interpolations.animatedHeight
: AnAnimated.Value
driving collapse/expand animations. It must be passed to theAnimatedSection
component as a prop.onLayout
: A function that measures a collapsible element. It must be passed to theAnimatedSection
component as a prop.onPress
: A function that toggles animation state when it's called. Pass it to aTouchable
component, that on press, is supposed to expand/collapse some content.
A component that takes care of height measuring and animating.
Basic usage:
<AnimatedSection
animatedHeight={animatedHeight}
onLayout={onLayout}
state={state}
>
<Text>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean quis erat
suscipit, mollis nibh ut, venenatis lectus.
</Text>
</AnimatedSection>
children
: (Required) Accepts a React element that will be rendered asAnimatedSection
content.animatedHeight
: (Required) AnAnimated.Value
driving collapse/expand animations. PassanimatedHeight
property returned byuseCollapsible
hook.onLayout
: (Required) A function that measures a collapsible element. PassonLayout
function returned byuseCollapsible
hook.state
: (Required) A state of the animation. It's used internally by the component to properly handle pointer events of the collapsed element. Passstate
property returned byuseCollapsible
hook.style
: (Optional) A custom style property that will be passed to the underlyingAnimated.View
- animated styles are supported.
See the contributing guide to learn how to contribute to the repository and the development workflow.
MIT