Shimmer Component
A React Native component that provides skeleton loading states with a smooth shimmer animation effect. Perfect for creating loading placeholders that match your content layout.
Features
- ✨ Smooth opacity animation with customizable duration
- 🎨 Fully customizable styling
- 📱 Lightweight and performant using React Native Reanimated
- 🔄 Infinite loop animation
- 🎯 TypeScript support
Installation
typescript
import Shimmer from '../components/shimmer';Basic Usage
tsx
import React from 'react';
import { View, StyleSheet } from 'react-native';
import Shimmer from '../components/shimmer';
export default function MyComponent() {
return (
<View style={styles.container}>
<Shimmer style={styles.titleShimmer} />
<Shimmer style={styles.subtitleShimmer} />
<Shimmer style={styles.bodyShimmer} />
</View>
);
}
const styles = StyleSheet.create({
container: {
padding: 16,
},
titleShimmer: {
height: 24,
backgroundColor: '#e9ecef',
borderRadius: 4,
width: '80%',
marginBottom: 8,
},
subtitleShimmer: {
height: 16,
backgroundColor: '#e9ecef',
borderRadius: 4,
width: '60%',
marginBottom: 8,
},
bodyShimmer: {
height: 14,
backgroundColor: '#e9ecef',
borderRadius: 4,
width: '100%',
},
});Props
| Prop | Type | Default | Description |
|---|---|---|---|
style | StyleProp<ViewStyle> | - | Custom styles for the shimmer element |
duration | number | 1000 | Animation duration in milliseconds |
Examples
Text Loading States
tsx
// Title shimmer
<Shimmer
style={{
height: 24,
backgroundColor: '#e9ecef',
borderRadius: 4,
width: '80%',
}}
/>
// Subtitle shimmer
<Shimmer
style={{
height: 16,
backgroundColor: '#e9ecef',
borderRadius: 4,
width: '60%',
}}
/>
// Body text shimmer
<Shimmer
style={{
height: 14,
backgroundColor: '#e9ecef',
borderRadius: 4,
width: '100%',
}}
/>Card Layout
tsx
<View style={styles.card}>
<Shimmer style={styles.cardImage} />
<View style={styles.cardContent}>
<Shimmer style={styles.cardTitle} />
<Shimmer style={styles.cardSubtitle} />
<Shimmer style={styles.cardText} />
</View>
</View>
const styles = StyleSheet.create({
card: {
backgroundColor: '#fff',
borderRadius: 12,
padding: 16,
borderWidth: 1,
borderColor: '#e9ecef',
},
cardImage: {
height: 120,
backgroundColor: '#e9ecef',
borderRadius: 8,
marginBottom: 12,
},
cardContent: {
gap: 8,
},
cardTitle: {
height: 20,
backgroundColor: '#e9ecef',
borderRadius: 4,
width: '70%',
},
cardSubtitle: {
height: 16,
backgroundColor: '#e9ecef',
borderRadius: 4,
width: '50%',
},
cardText: {
height: 14,
backgroundColor: '#e9ecef',
borderRadius: 4,
width: '90%',
},
});List Item
tsx
<View style={styles.listItem}>
<Shimmer style={styles.avatar} />
<View style={styles.content}>
<Shimmer style={styles.title} />
<Shimmer style={styles.subtitle} />
</View>
</View>
const styles = StyleSheet.create({
listItem: {
flexDirection: 'row',
alignItems: 'center',
paddingVertical: 12,
},
avatar: {
width: 40,
height: 40,
backgroundColor: '#e9ecef',
borderRadius: 20,
marginRight: 12,
},
content: {
flex: 1,
gap: 6,
},
title: {
height: 16,
backgroundColor: '#e9ecef',
borderRadius: 4,
width: '60%',
},
subtitle: {
height: 14,
backgroundColor: '#e9ecef',
borderRadius: 4,
width: '40%',
},
});Custom Shapes
tsx
// Circle
<Shimmer
style={{
width: 60,
height: 60,
backgroundColor: '#e9ecef',
borderRadius: 30,
}}
/>
// Square
<Shimmer
style={{
width: 60,
height: 60,
backgroundColor: '#e9ecef',
borderRadius: 4,
}}
/>
// Rounded rectangle
<Shimmer
style={{
width: 60,
height: 60,
backgroundColor: '#e9ecef',
borderRadius: 12,
}}
/>Custom Animation Duration
tsx
<Shimmer
duration={2000} // 2 seconds per cycle
style={styles.customShimmer}
/>