SkeletonGroup

Coordinates multiple skeleton loading placeholders with centralized animation control.

Import

import { SkeletonGroup } from 'heroui-native';

Anatomy

<SkeletonGroup>
  <SkeletonGroup.Item />
</SkeletonGroup>
  • SkeletonGroup: Root container that provides centralized control for all skeleton items
  • SkeletonGroup.Item: Individual skeleton item that inherits props from the parent group

Usage

Basic Usage

The SkeletonGroup component manages multiple skeleton items with shared loading state and animation.

<SkeletonGroup isLoading={isLoading}>
  <SkeletonGroup.Item className="h-4 w-full rounded-md" />
  <SkeletonGroup.Item className="h-4 w-3/4 rounded-md" />
  <SkeletonGroup.Item className="h-4 w-1/2 rounded-md" />
</SkeletonGroup>

With Container Layout

Use className on the group to control layout of skeleton items.

<SkeletonGroup isLoading={isLoading} className="flex-row items-center gap-3">
  <SkeletonGroup.Item className="h-12 w-12 rounded-lg" />
  <View className="flex-1 gap-1.5">
    <SkeletonGroup.Item className="h-4 w-full rounded-md" />
    <SkeletonGroup.Item className="h-3 w-2/3 rounded-md" />
  </View>
</SkeletonGroup>

With isSkeletonOnly for Pure Skeleton Layouts

Use isSkeletonOnly when the group contains only skeleton placeholders with layout wrappers (like View) that have no content to render in the loaded state. This prop hides the entire group when isLoading is false, preventing empty containers from affecting your layout.

<SkeletonGroup
  isLoading={isLoading}
  isSkeletonOnly // Hides entire group when isLoading is false
  className="flex-row items-center gap-3"
>
  <SkeletonGroup.Item className="h-12 w-12 rounded-lg" />
  {/* This View is only for layout, no content */}
  <View className="flex-1 gap-1.5">
    <SkeletonGroup.Item className="h-4 w-full rounded-md" />
    <SkeletonGroup.Item className="h-3 w-2/3 rounded-md" />
  </View>
</SkeletonGroup>

With Animation Variants

Control animation style for all items in the group.

<SkeletonGroup isLoading={isLoading} variant="pulse">
  <SkeletonGroup.Item className="h-10 w-10 rounded-full" />
  <SkeletonGroup.Item className="h-4 w-32 rounded-md" />
  <SkeletonGroup.Item className="h-3 w-24 rounded-md" />
</SkeletonGroup>

With Custom Animation Configuration

Configure shimmer or pulse animations for the entire group.

<SkeletonGroup
  isLoading={isLoading}
  variant="shimmer"
  animation={{
    shimmer: {
      duration: 2000,
      highlightColor: 'rgba(59, 130, 246, 0.3)',
    },
  }}
>
  <SkeletonGroup.Item className="h-16 w-full rounded-lg" />
  <SkeletonGroup.Item className="h-4 w-3/4 rounded-md" />
</SkeletonGroup>

With Enter/Exit Animations

Apply Reanimated transitions when the group appears or disappears.

<SkeletonGroup
  entering={FadeInLeft}
  exiting={FadeOutRight}
  isLoading={isLoading}
  className="w-full gap-2"
>
  <SkeletonGroup.Item className="h-4 w-full rounded-md" />
  <SkeletonGroup.Item className="h-4 w-3/4 rounded-md" />
</SkeletonGroup>

Example

import { Card, SkeletonGroup, Avatar } from 'heroui-native';
import { useState } from 'react';
import { Text, View, Image } from 'react-native';

export default function SkeletonGroupExample() {
  const [isLoading, setIsLoading] = useState(true);

  return (
    <SkeletonGroup isLoading={isLoading}>
      <Card className="p-4">
        <Card.Header>
          <View className="flex-row items-center gap-3 mb-4">
            <SkeletonGroup.Item className="h-10 w-10 rounded-full">
              <Avatar size="sm" alt="Avatar">
                <Avatar.Image
                  source={{ uri: 'https://i.pravatar.cc/150?img=4' }}
                />
                <Avatar.Fallback />
              </Avatar>
            </SkeletonGroup.Item>

            <View className="flex-1 gap-1">
              <SkeletonGroup.Item className="h-3 w-32 rounded-md">
                <Text className="font-semibold text-foreground">John Doe</Text>
              </SkeletonGroup.Item>
              <SkeletonGroup.Item className="h-3 w-24 rounded-md">
                <Text className="text-sm text-muted">@johndoe</Text>
              </SkeletonGroup.Item>
            </View>
          </View>

          <View className="mb-4 gap-1.5">
            <SkeletonGroup.Item className="h-4 w-full rounded-md">
              <Text className="text-base text-foreground">
                This is the first line of the post content.
              </Text>
            </SkeletonGroup.Item>
            <SkeletonGroup.Item className="h-4 w-full rounded-md">
              <Text className="text-base text-foreground">
                Second line with more interesting content to read.
              </Text>
            </SkeletonGroup.Item>
            <SkeletonGroup.Item className="h-4 w-2/3 rounded-md">
              <Text className="text-base text-foreground">
                Last line is shorter.
              </Text>
            </SkeletonGroup.Item>
          </View>
        </Card.Header>

        <SkeletonGroup.Item className="h-48 w-full rounded-lg">
          <View className="h-48 bg-surface-tertiary rounded-lg overflow-hidden">
            <Image
              source={{
                uri: 'https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/backgrounds/cards/car1.jpg',
              }}
              className="h-full w-full"
            />
          </View>
        </SkeletonGroup.Item>
      </Card>
    </SkeletonGroup>
  );
}

API Reference

SkeletonGroup

proptypedefaultdescription
childrenReact.ReactNode-SkeletonGroup.Item components and layout elements
isLoadingbooleantrueWhether the skeleton items are currently loading
isSkeletonOnlybooleanfalseHides entire group when isLoading is false (for skeleton-only layouts)
variant'shimmer' | 'pulse' | 'none''shimmer'Animation variant for all items in the group
animationSkeletonRootAnimation-Animation configuration
classNamestring-Additional CSS classes for the group container
styleStyleProp<ViewStyle>-Custom styles for the group container
...Animated.ViewPropsAnimatedProps<ViewProps>-All Reanimated Animated.View props are supported

SkeletonRootAnimation

Animation configuration for SkeletonGroup component. Can be:

  • false or "disabled": Disable only root animations
  • "disable-all": Disable all animations including children
  • true or undefined: Use default animations
  • object: Custom animation configuration
proptypedefaultdescription
entering.valueEntryOrExitLayoutTypeFadeInCustom entering animation
exiting.valueEntryOrExitLayoutTypeFadeOutCustom exiting animation
shimmer.durationnumber1500Animation duration in milliseconds
shimmer.speednumber1Speed multiplier for the animation
shimmer.highlightColorstring-Highlight color for the shimmer effect
shimmer.easingEasingFunctionEasing.linearEasing function for the animation
pulse.durationnumber1000Animation duration in milliseconds
pulse.minOpacitynumber0.5Minimum opacity value
pulse.maxOpacitynumber1Maximum opacity value
pulse.easingEasingFunctionEasing.inOut(Easing.ease)Easing function for the animation

SkeletonGroup.Item

proptypedefaultdescription
childrenReact.ReactNode-Content to show when not loading
isLoadingbooleaninheritedWhether the skeleton is currently loading (overrides group setting)
variant'shimmer' | 'pulse' | 'none'inheritedAnimation variant (overrides group setting)
animationSkeletonRootAnimationinheritedAnimation configuration (overrides group setting)
classNamestring-Additional CSS classes for styling the item
...Animated.ViewPropsAnimatedProps<ViewProps>-All Reanimated Animated.View props are supported

Special Notes

Props Inheritance

SkeletonGroup.Item components inherit all animation-related props from their parent SkeletonGroup:

  • isLoading
  • variant
  • animation

Individual items can override any inherited prop by providing their own value.

On this page