managarten/apps/picture/packages/mobile-ui/components/ui/Skeleton
Wuesteon d36b321d9d style: auto-format codebase with Prettier
Applied formatting to 1487+ files using pnpm format:write
  - TypeScript/JavaScript files
  - Svelte components
  - Astro pages
  - JSON configs
  - Markdown docs

  13 files still need manual review (Astro JSX comments)
2025-11-27 18:33:16 +01:00
..
index.ts refactor: restructure 2025-11-26 03:03:24 +01:00
README.md refactor: restructure 2025-11-26 03:03:24 +01:00
Skeleton.tsx style: auto-format codebase with Prettier 2025-11-27 18:33:16 +01:00

Skeleton

Loading skeleton with shimmer animation for placeholder content.

Features

  • Shimmer animation
  • 3 variants: rect, circle, text
  • Custom dimensions and colors
  • SkeletonGroup for layouts
  • Built with Reanimated

Installation

npx @memoro/ui add skeleton

Dependencies: react-native-reanimated

Usage

Rectangle (Default)

import { Skeleton } from '@/components/ui/Skeleton';

<Skeleton width={200} height={100} />

Circle (Avatar)

<Skeleton variant="circle" width={50} height={50} />

Text Line

<Skeleton variant="text" width="80%" />
<Skeleton variant="text" width="60%" />

Custom Colors

<Skeleton
  width={200}
  height={20}
  backgroundColor="#D1D5DB"
  shimmerColor="#E5E7EB"
/>

Card Skeleton

<SkeletonGroup spacing={12}>
  <Skeleton variant="circle" width={50} height={50} />
  <Skeleton variant="text" width="70%" />
  <Skeleton variant="text" width="50%" />
</SkeletonGroup>

List Skeleton

{Array.from({ length: 5 }).map((_, i) => (
  <SkeletonGroup key={i} spacing={8} style={{ marginBottom: 16 }}>
    <Skeleton variant="circle" width={40} height={40} />
    <View style={{ flex: 1 }}>
      <Skeleton variant="text" width="80%" />
      <Skeleton variant="text" width="60%" />
    </View>
  </SkeletonGroup>
))}

Image Grid Skeleton

<View style={{ flexDirection: 'row', flexWrap: 'wrap', gap: 8 }}>
  {Array.from({ length: 6 }).map((_, i) => (
    <Skeleton key={i} width={100} height={100} />
  ))}
</View>

Props

Skeleton

Prop Type Default Description
width number | string '100%' Width of skeleton
height number | string 20 Height of skeleton
borderRadius number - Border radius (auto for variants)
backgroundColor string '#E5E7EB' Base color
shimmerColor string '#F3F4F6' Shimmer overlay color
duration number 1500 Animation duration (ms)
style ViewStyle - Additional styles
variant 'rect' | 'circle' | 'text' 'rect' Skeleton shape

SkeletonGroup

Prop Type Default Description
children ReactNode - Skeleton elements
spacing number 12 Gap between elements
style ViewStyle - Container styles

Variants

Variant Default Radius Use Case
rect 8px Images, cards, boxes
circle 50% Avatars, icons
text 4px Text lines

Examples

Profile Card Skeleton

<View style={{ padding: 16 }}>
  <SkeletonGroup spacing={16}>
    {/* Avatar */}
    <Skeleton variant="circle" width={80} height={80} />

    {/* Name */}
    <Skeleton variant="text" width="60%" height={24} />

    {/* Bio */}
    <SkeletonGroup spacing={8}>
      <Skeleton variant="text" width="100%" />
      <Skeleton variant="text" width="90%" />
      <Skeleton variant="text" width="70%" />
    </SkeletonGroup>

    {/* Stats */}
    <View style={{ flexDirection: 'row', gap: 16 }}>
      <Skeleton width={80} height={40} />
      <Skeleton width={80} height={40} />
      <Skeleton width={80} height={40} />
    </View>
  </SkeletonGroup>
</View>

Article Skeleton

<SkeletonGroup spacing={16}>
  {/* Cover image */}
  <Skeleton width="100%" height={200} />

  {/* Title */}
  <Skeleton variant="text" width="90%" height={28} />
  <Skeleton variant="text" width="70%" height={28} />

  {/* Meta */}
  <View style={{ flexDirection: 'row', gap: 12 }}>
    <Skeleton variant="circle" width={32} height={32} />
    <Skeleton variant="text" width={120} />
  </View>

  {/* Content */}
  <SkeletonGroup spacing={8}>
    <Skeleton variant="text" width="100%" />
    <Skeleton variant="text" width="95%" />
    <Skeleton variant="text" width="98%" />
    <Skeleton variant="text" width="85%" />
  </SkeletonGroup>
</SkeletonGroup>

Default Colors

  • Background: #E5E7EB (gray-200)
  • Shimmer: #F3F4F6 (gray-100)

Animation

  • Pulses from 30% → 60% → 30% opacity
  • Duration: 1500ms
  • Infinite loop

Dependencies

  • react-native-reanimated (v3+)

Notes

  • Uses Reanimated for smooth 60fps animation
  • Shimmer color should be lighter than background
  • Use SkeletonGroup for consistent spacing
  • Supports percentage widths