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
| prop | type | default | description |
|---|---|---|---|
children | React.ReactNode | - | SkeletonGroup.Item components and layout elements |
isLoading | boolean | true | Whether the skeleton items are currently loading |
isSkeletonOnly | boolean | false | Hides entire group when isLoading is false (for skeleton-only layouts) |
variant | 'shimmer' | 'pulse' | 'none' | 'shimmer' | Animation variant for all items in the group |
animation | SkeletonRootAnimation | - | Animation configuration |
className | string | - | Additional CSS classes for the group container |
style | StyleProp<ViewStyle> | - | Custom styles for the group container |
...Animated.ViewProps | AnimatedProps<ViewProps> | - | All Reanimated Animated.View props are supported |
SkeletonRootAnimation
Animation configuration for SkeletonGroup component. Can be:
falseor"disabled": Disable only root animations"disable-all": Disable all animations including childrentrueorundefined: Use default animationsobject: Custom animation configuration
| prop | type | default | description |
|---|---|---|---|
entering.value | EntryOrExitLayoutType | FadeIn | Custom entering animation |
exiting.value | EntryOrExitLayoutType | FadeOut | Custom exiting animation |
shimmer.duration | number | 1500 | Animation duration in milliseconds |
shimmer.speed | number | 1 | Speed multiplier for the animation |
shimmer.highlightColor | string | - | Highlight color for the shimmer effect |
shimmer.easing | EasingFunction | Easing.linear | Easing function for the animation |
pulse.duration | number | 1000 | Animation duration in milliseconds |
pulse.minOpacity | number | 0.5 | Minimum opacity value |
pulse.maxOpacity | number | 1 | Maximum opacity value |
pulse.easing | EasingFunction | Easing.inOut(Easing.ease) | Easing function for the animation |
SkeletonGroup.Item
| prop | type | default | description |
|---|---|---|---|
children | React.ReactNode | - | Content to show when not loading |
isLoading | boolean | inherited | Whether the skeleton is currently loading (overrides group setting) |
variant | 'shimmer' | 'pulse' | 'none' | inherited | Animation variant (overrides group setting) |
animation | SkeletonRootAnimation | inherited | Animation configuration (overrides group setting) |
className | string | - | Additional CSS classes for styling the item |
...Animated.ViewProps | AnimatedProps<ViewProps> | - | All Reanimated Animated.View props are supported |
Special Notes
Props Inheritance
SkeletonGroup.Item components inherit all animation-related props from their parent SkeletonGroup:
isLoadingvariantanimation
Individual items can override any inherited prop by providing their own value.