Back to Components

Shimmer Pressable View

Essential comps
about 2 months ago

About

Shimmer Effect Component

A highly customizable shimmer effect component for React Native Expo with smooth spring animations. Perfect for creating premium UI effects like loading states, highlight animations, and paywall subscriptions.

Features

  • ✨ Smooth spring-based animations
  • 🎨 Fully customizable colors, angles, and timing
  • 📏 Dynamic stripe configuration
  • 🚀 Zero-delay first animation
  • 💫 Gradient opacity support (center to edges)

Installation

tsx
import { ShimmerPressableView } from '@/components/shimmer-pressable-view'; import { ShimmerEffectStripe } from '@/components/shimmer-effect-stripe';

Basic Usage

Simple Shimmer Button

tsx
import { ShimmerPressableView } from '@/components/shimmer-pressable-view'; <ShimmerPressableView shimmer onPress={() => console.log('Pressed')} > <Text>Click me</Text> </ShimmerPressableView>

With Custom Configuration

tsx
<ShimmerPressableView shimmer shimmerConfig={{ delay: 2000, duration: 2000, angle: 30, color: 'rgba(255, 215, 0, 0.3)', stripeCount: 5, }} backgroundColor="#155A3A" borderRadius={16} onPress={handlePress} > <Text>Premium Button</Text> </ShimmerPressableView>

API Reference

ShimmerPressableView Props

PropTypeDefaultDescription
shimmerbooleantrueEnable shimmer effect
withShimmerboolean-Alias for shimmer (deprecated)
shimmerConfigShimmerConfig-Shimmer configuration object
pressScalenumber0.95Scale value when pressed (0-1)
pressDurationnumber200Animation duration for press feedback (ms)
containerStyleViewStyle-Custom container style
contentStyleViewStyle-Custom content style
backgroundColorstring'#2C2C2E'Background color
widthnumber-Button width (optional, uses flex if not provided)
heightnumber-Button height (optional, uses flex if not provided)
borderRadiusnumber24Border radius
onPressIn() => void-Custom onPressIn handler
onPressOut() => void-Custom onPressOut handler
childrenReact.ReactNode-Button content

ShimmerConfig

PropertyTypeDefaultDescription
delaynumber2000Delay between shimmer cycles (ms)
durationnumber1100Base duration for shimmer animation (ms)
anglenumber30Rotation angle in degrees
colorstring'rgba(180, 180, 180, 0.2)'Shimmer color
stripesShimmerStripe[]-Custom stripe configuration array
stripeCountnumber3Number of stripes (only used if stripes is not provided)

ShimmerStripe

PropertyTypeDescription
widthnumberWidth of the stripe
opacitynumberOpacity of the stripe (0-1)

Advanced Examples

Custom Stripe Configuration

Create a custom gradient effect with specific stripe widths and opacities:

tsx
<ShimmerPressableView shimmer shimmerConfig={{ color: 'rgba(255, 215, 0, 0.3)', stripes: [ { width: 30, opacity: 0.2 }, { width: 25, opacity: 0.6 }, { width: 20, opacity: 1.0 }, { width: 25, opacity: 0.6 }, { width: 30, opacity: 0.2 }, ], }} > <Text>Custom Gradient</Text> </ShimmerPressableView>

Multiple Stripe Count

Use more stripes for a smoother effect. Stripe opacity is calculated automatically based on the number of stripes:

  • Stripe 1: ~0.3 opacity
  • Stripe 2: ~0.65 opacity
  • Stripe 3: 1.0 opacity
  • Stripe 4: ~0.65 opacity
  • Stripe 5: ~0.3 opacity
  • Stripe 6: ~0.15 opacity
  • Stripe 7: ~0.075 opacity

Try to use an odd number of stripes for a more natural effect.

tsx
<ShimmerPressableView shimmer shimmerConfig={{ stripeCount: 7, color: 'rgba(255, 255, 255, 0.25)', }} > <Text>Smooth Shimmer</Text> </ShimmerPressableView>

Paywall Integration

Perfect for highlighting premium subscription options:

tsx
<Pressable style={styles.subscriptionCard}> <ShimmerPressableView shimmer shimmerConfig={{ delay: 2000, duration: 2000, angle: 30, color: 'rgba(255, 215, 0, 0.3)', stripeCount: 5, }} containerStyle={{ position: 'absolute', top: 0, left: 0, right: 0, bottom: 0, }} backgroundColor="transparent" borderRadius={16} pointerEvents="none" /> <View style={styles.cardContent}> <Text>Annual Pass</Text> <Text>$25</Text> </View> </Pressable>

Default Stripe Pattern

When using stripeCount without custom stripes, the component automatically generates a gradient pattern:

  • Center stripe: Highest opacity (1.0), wider width
  • Edge stripes: Lower opacity (~0.3), narrower width
  • Gradient: Smooth transition from center to edges

For example, with stripeCount: 5:

  • Stripe 1 (left): ~0.3 opacity, 16px width
  • Stripe 2: ~0.65 opacity, 20px width
  • Stripe 3 (center): 1.0 opacity, 24px width
  • Stripe 4: ~0.65 opacity, 20px width
  • Stripe 5 (right): ~0.3 opacity, 16px width

Spring Animation Configuration

The shimmer uses spring physics for smooth, natural animations:

tsx
withSpring(targetValue, { damping: 25, // Controls oscillation (higher = less bounce) stiffness: 60, // Controls speed (higher = faster) mass: 1.2, // Controls inertia (higher = slower) })

Adjust these values in the component code to fine-tune the animation feel.

Best Practices

  1. Color Selection: Use semi-transparent colors (e.g., rgba(255, 215, 0, 0.3)) for subtle effects
  2. Stripe Count: Use 3-5 stripes for most cases, 7+ for very smooth gradients
  3. Delay Timing: 2000-3000ms delay works well for most UI contexts
  4. Angle: 30 degrees is optimal for most use cases
  5. Performance: The component is optimized to prevent unnecessary re-animations

Troubleshooting

Animation doesn't start

  • Ensure shimmer prop is true
  • Check that container has a valid width (component measures layout automatically)

Animation restarts on re-render

  • This is prevented automatically, but if issues persist, check that the component isn't being unmounted/remounted

Too fast/slow animation

  • Adjust damping, stiffness, and mass values in the spring configuration
  • Modify delay for timing between cycles

TypeScript Support

Full TypeScript support with exported interfaces:

tsx
import type { ShimmerConfig, ShimmerStripe } from '@/components/shimmer-pressable-view';

License

Part of the react native components library.

Posted by

E

eren

@eren