This repository isn't an official repository; you can use this repo while the library has not been updated to support Expo SDK 45. Remember to check the official repository regularly.
- tested for Expo 45
- expo-linear-gradient : 10.0.3 => 11.3.0
- react-native-reanimated : 2.2.0 => 2.8.0
If you are not using expo, please head up to this page instead.
React native Skeleton Content, a simple yet fully customizable component made to achieve loading animation in a Skeleton-style. Works in both iOS and Android.
- The package has been rewritten to Hooks and is using the declarative react-native-reanimated package for animations
- It now supports nested layouts for children bones, see an example on this snack
- It finally supports percentages dimensions for bones, for any type of animation!
npm install react-native-skeleton-content
- Import react-native-skeleton-content:
import SkeletonContent from 'react-native-skeleton-content';
- Once you create the SkeletonContent, you have two options:
- Child Layout : The component will figure out the layout of its bones with the dimensions of its direct children.
- Custom Layout : You provide a prop
layout
to the component specifying the size of the bones (see the Examples section below). Below is an example with a custom layout. A key prop for each child is optional but highly recommended.
export default function Placeholder() {
return (
<SkeletonContent
containerStyle={{ flex: 1, width: 300 }}
isLoading={false}
layout={[
{ key: 'someId', width: 220, height: 20, marginBottom: 6 },
{ key: 'someOtherId', width: 180, height: 20, marginBottom: 6 }
]}
>
<Text style={styles.normalText}>Your content</Text>
<Text style={styles.bigText}>Other content</Text>
</SkeletonContent>
);
}
- Then simply sync the prop
isLoading
to your state to show/hide the SkeletonContent when the assets/data are available to the user.
export default function Placeholder () {
const [loading, setLoading] = useState(true);
return (
<SkeletonContent
containerStyle={{flex: 1, width: 300}}
isLoading={isLoading}>
{...otherProps}
/>
)
}
Name | Type | Default | Description |
---|---|---|---|
isLoading | bool | required | Shows the Skeleton bones when true |
layout | array of objects | [] | A custom layout for the Skeleton bones |
duration | number | 1200 ms | Duration of one cycle of animation |
containerStyle | object | flex: 1 | The style applied to the View containing the bones |
easing | Easing | bezier(0.5, 0, 0.25, 1) | Easing of the bones animation |
animationType | string | "shiver" | The animation to be used for animating the bones (see demos below) |
animationDirection | string | "horizontalRight" | Used only for shiver animation, describes the direction and end-point (ex: horizontalRight goes on the x-axis from left to right) |
boneColor | string | "#E1E9EE" | Color of the bones |
highlightColor | string | "#F2F8FC" | Color of the highlight of the bones |
Note: The Easing type function is the one provided by react-native-reanimated, so if you want to change the default you will have to install it as a dependency.
See the playground section to experiment : 1 - Changing the direction of the animation (animationDirection prop) :
export default function Placeholder () {
return (
<SkeletonContent
containerStyle={{flex: 1, width: 300}}
animationDirection="horizontalLeft"
isLoading={true}>
...
/>
)
}
2 - Changing the colors and switching to "pulse" animation (boneColor, highlightColor and animationType prop) :
export default function Placeholder () {
return (
<SkeletonContent
containerStyle={{flex: 1, width: 300}}
boneColor="#121212"
highlightColor="#333333"
animationType="pulse"
isLoading={true}>
...
/>
)
}
3 - Customizing the layout of the bones (layout prop) :
export default function Placeholder () {
return (
<SkeletonContent
containerStyle={{flex: 1, width: 300}}
animationDirection="horizontalLeft"
layout={[
// long line
{ width: 220, height: 20, marginBottom: 6 },
// short line
{ width: 180, height: 20, marginBottom: 6 },
...
]}
isLoading={true}>
...
/>
)
}
You can test out the features and different props easily on Snack. Don't hesitate to take contact if anything is unclear !