logoChisa UI

Command Palette

Search for a command to run...

Componentschevron_rightSkeleton

Skeleton

Skeleton loader with shimmer effect for loading states.

9:41
signal_cellular_altwifibattery_full

Preview Controls

Animation

Shimmer loading effect

This is a CSS-based preview of the animation. The actual React Native component uses physics-based springs for a more natural feel.

Installation

$

Usage

Example.tsx
import { Skeleton } from './components/Skeleton';
export default function LoadingScreen() {
return (
<View>
<Skeleton width="100%" height={200} borderRadius={12} />
<Skeleton width="60%" height={20} style={{ marginTop: 16 }} />
<Skeleton width="40%" height={16} style={{ marginTop: 8 }} />
</View>
);
}

Full Component Code

Skeleton.tsx
1import React, { useEffect } from 'react';
2import { ViewStyle, StyleProp, StyleSheet, DimensionValue } from 'react-native';
3import Animated, {
4 useSharedValue,
5 useAnimatedStyle,
6 withRepeat,
7 withTiming,
8 Easing,
9 interpolate,
10} from 'react-native-reanimated';
11import { LinearGradient } from 'expo-linear-gradient';
12
13interface SkeletonProps {
14 width?: DimensionValue;
15 height?: number;
16 borderRadius?: number;
17 duration?: number;
18 style?: StyleProp<ViewStyle>;
19}
20
21export const Skeleton: React.FC<SkeletonProps> = ({
22 width = '100%',
23 height = 20,
24 borderRadius = 8,
25 duration = 1500,
26 style,
27}) => {
28 const shimmer = useSharedValue(0);
29
30 useEffect(() => {
31 shimmer.value = withRepeat(
32 withTiming(1, {
33 duration,
34 easing: Easing.linear,
35 }),
36 -1,
37 false
38 );
39 }, []);
40
41 const animatedStyle = useAnimatedStyle(() => ({
42 transform: [
43 {
44 translateX: interpolate(
45 shimmer.value,
46 [0, 1],
47 [-200, 200]
48 ),
49 },
50 ],
51 }));
52
53 return (
54 <Animated.View
55 style={[
56 styles.skeleton,
57 { width, height, borderRadius },
58 style,
59 ]}
60 >
61 <Animated.View style={[styles.shimmer, animatedStyle]}>
62 <LinearGradient
63 colors={['transparent', 'rgba(255,255,255,0.3)', 'transparent']}
64 start={{ x: 0, y: 0 }}
65 end={{ x: 1, y: 0 }}
66 style={styles.gradient}
67 />
68 </Animated.View>
69 </Animated.View>
70 );
71};
72
73const styles = StyleSheet.create({
74 skeleton: {
75 backgroundColor: '#E5E5E5',
76 overflow: 'hidden',
77 },
78 shimmer: {
79 ...StyleSheet.absoluteFillObject,
80 },
81 gradient: {
82 flex: 1,
83 width: 200,
84 },
85});
86
87export default Skeleton;

Props

NameTypeDefaultDescription
widthnumber | string'100%'Width of skeleton
heightnumber20Height of skeleton
borderRadiusnumber8Border radius
durationnumber1500Shimmer cycle duration