Skip to content
Docs
Components
Skeleton

Skeleton

The Skeleton component provides animated placeholders while content is loading. It supports different shapes and automatically adapts to dark mode.

Import

import { Skeleton, SkeletonProvider } from "react-native-ficus-ui";

Usage

Basic skeleton

EDITABLE EXAMPLE
<VStack spacing="md">
  <Skeleton w="200" h="20" />
  <Skeleton w="150" h="15" />
  <Skeleton w="300" h="12" />
</VStack>

Skeleton Box

EDITABLE EXAMPLE
<VStack spacing="md">
  <Skeleton.Box w="100%" h="100" />
  <Skeleton.Box w="200" h="50" borderRadius="lg" />
  <Skeleton.Box w="150" h="30" borderRadius="full" />
</VStack>

Skeleton Text

EDITABLE EXAMPLE
<VStack spacing="md">
  <Skeleton.Text fontSize="sm" />
  <Skeleton.Text fontSize="md" />
  <Skeleton.Text fontSize="lg" />
  <Skeleton.Text fontSize="xl" />
  <Skeleton.Text fontSize="2xl" />
</VStack>

Multi-line text skeleton

EDITABLE EXAMPLE
<VStack spacing="lg">
  <Skeleton.Text noOfLines={2} />
  <Skeleton.Text noOfLines={3} lineSpacing="md" />
  <Skeleton.Text noOfLines={4} lineSpacing="lg" />
</VStack>

Skeleton Circle

EDITABLE EXAMPLE
<HStack spacing="md">
  <Skeleton.Circle boxSize="30" />
  <Skeleton.Circle boxSize="50" />
  <Skeleton.Circle boxSize="70" />
  <Skeleton.Circle boxSize="100" />
</HStack>

Loading state with content

EDITABLE EXAMPLE
function LoadingExample() {
  const [isLoaded, setIsLoaded] = React.useState(false);
  
  React.useEffect(() => {
    const timer = setTimeout(() => setIsLoaded(true), 3000);
    return () => clearTimeout(timer);
  }, []);

  return (
    <VStack spacing="md">
      <Button onPress={() => setIsLoaded(!isLoaded)}>
        {isLoaded ? 'Show Skeleton' : 'Show Content'}
      </Button>
      
      <Skeleton isLoaded={isLoaded}>
        <Text>This content appears when loaded!</Text>
      </Skeleton>
      
      <Skeleton.Text fontSize="lg" isLoaded={isLoaded}>
        <Text fontSize="lg" fontWeight="bold">
          This is a loaded text with large font size
        </Text>
      </Skeleton.Text>
    </VStack>
  );
}

Synchronized animation with SkeletonProvider

EDITABLE EXAMPLE
<SkeletonProvider>
  <VStack spacing="md">
    <HStack spacing="md" alignItems="center">
      <Skeleton.Circle boxSize="50" />
      <VStack flex={1} spacing="xs">
        <Skeleton.Text fontSize="lg" w="70%" />
        <Skeleton.Text fontSize="sm" w="50%" />
      </VStack>
    </HStack>
    
    <Skeleton.Box w="100%" h="100" borderRadius="md" />
    
    <Skeleton.Text noOfLines={3} />
  </VStack>
</SkeletonProvider>

Card layout example

EDITABLE EXAMPLE
<Box bg="white" p="lg" borderRadius="lg" shadow="sm">
  <SkeletonProvider>
    <VStack spacing="md">
      <HStack spacing="md" alignItems="center">
        <Skeleton.Circle boxSize="40" />
        <VStack flex={1} spacing="xs">
          <Skeleton.Text w="60%" />
          <Skeleton.Text w="40%" fontSize="sm" />
        </VStack>
      </HStack>
      
      <Skeleton.Box h="120" borderRadius="md" />
      
      <VStack spacing="xs">
        <Skeleton.Text />
        <Skeleton.Text />
        <Skeleton.Text w="80%" />
      </VStack>
    </VStack>
  </SkeletonProvider>
</Box>

Custom shimmer settings

EDITABLE EXAMPLE
<VStack spacing="lg">
  <Text fontSize="md" fontWeight="bold">Default shimmer (enabled)</Text>
  <Skeleton.Box w="200" h="30" />
  
  <Text fontSize="md" fontWeight="bold">No shimmer animation</Text>
  <Skeleton.Box w="200" h="30" shimmer={false} />
  
  <Text fontSize="md" fontWeight="bold">Custom animation duration</Text>
  <SkeletonProvider duration={800}>
    <Skeleton.Box w="200" h="30" />
  </SkeletonProvider>
</VStack>

Props

Skeleton

Extends every Box props.

isLoaded

If true, the skeleton will be replaced by the children.

TypeRequiredDefault
booleanNofalse

shimmer

If true, the skeleton will show a shimmer animation.

TypeRequiredDefault
booleanNotrue

duration

The duration of the shimmer animation in milliseconds. Overrides provider duration.

TypeRequiredDefault
numberNo1200

Skeleton.Text

Extends every Skeleton props.

fontSize

The font size to calculate the skeleton height automatically.

TypeRequiredDefault
ResponsiveValue<string | number>No'md'

noOfLines

The number of lines to render for multi-line text skeleton.

TypeRequiredDefault
numberNo1

lineSpacing

The spacing between lines when noOfLines > 1.

TypeRequiredDefault
ResponsiveValue<string | number>No'xs'

Skeleton.Circle

Extends every Skeleton props.

boxSize

The size of the circle (both width and height).

TypeRequiredDefault
ResponsiveValue<number | string>No40

SkeletonProvider

duration

The duration of the shimmer animation in milliseconds for all child skeleton components.

TypeRequiredDefault
numberNo1200

paused

If true, the shimmer animation will be paused.

TypeRequiredDefault
booleanNofalse

Accessibility

The Skeleton component includes proper accessibility features:

  • Automatically sets appropriate accessibilityLabel when content is loading
  • Maintains proper screen reader support
  • Respects user's reduced motion preferences

Styling

Skeleton components can be styled using all standard Ficus UI style props:

EDITABLE EXAMPLE
<VStack spacing="md">
  <Skeleton.Box 
    w="200" 
    h="30" 
    bg="blue.100" 
    borderRadius="full"
    borderWidth={2}
    borderColor="blue.300"
  />
  
  <Skeleton.Text 
    fontSize="lg"
    bg="red.100"
    borderRadius="md"
    p="sm"
  />
  
  <Skeleton.Circle 
    boxSize="60"
    bg="green.200"
    borderWidth={3}
    borderColor="green.400"
  />
</VStack>

Performance

The Skeleton component is optimized for performance:

  • Uses react-native-reanimated for 60fps animations
  • Pure React Native implementation - no external native dependencies
  • Lightweight shimmer effect with minimal CPU usage
  • Works perfectly in Expo Go and all React Native environments