Skeleton

Shimmer placeholder for loading content.

A shimmer placeholder for content that has not loaded yet.

Size it with Tailwind utilities, matching the shape of what is coming — a placeholder that is the wrong size moves the page when the real content lands.

For a shimmer over content that is there, use Shimmer.

Installation

Skeleton ships with the library — no separate install.

import { Skeleton, Card, Text } from 'panelui-native';

Or copy the source into your project, to own and edit it:

npx panelui-cli@latest add skeleton

Usage

<View className="flex-row items-center gap-3">
  <Skeleton className="h-12 w-12 rounded-full" />
  <View className="flex-1 gap-2">
    <Skeleton className="h-4 w-3/4" />
    <Skeleton className="h-4 w-1/2" />
  </View>
</View>

Examples

A loading card

Match the shape of the real content — a skeleton that is the wrong size is worse than none, because the layout jumps when the data lands.

<Card>
  <Card.Content className="gap-3 p-4">
    <Skeleton className="h-5 w-1/2" />
    <Skeleton className="h-4 w-full" />
    <Skeleton className="h-4 w-4/5" />
  </Card.Content>
</Card>

An avatar and two lines

<View className="flex-row items-center gap-3">
  <Skeleton className="h-10 w-10 rounded-full" />
  <View className="flex-1 gap-2">
    <Skeleton className="h-4 w-1/3" />
    <Skeleton className="h-3 w-2/3" />
  </View>
</View>

Swapped for the real thing

{loading ? (
  <Skeleton className="h-6 w-32" />
) : (
  <Text size="xl" weight="semibold">{user.name}</Text>
)}

Announcing the wait

One label for the whole region, not one per row.

<View className="gap-3">
  <Skeleton className="h-4 w-3/4" label="Loading your orders" />
  <Skeleton className="h-4 w-full" />
  <Skeleton className="h-4 w-2/3" />
</View>

API Reference

Skeleton

PropTypeDefaultDescription
classNamestring
labelstringWhat is loading, for a screen reader. Setting it makes this skeleton announce as a busy status; leaving it unset keeps the placeholder out of the accessibility tree entirely. A screen full of placeholders needs one of them labelled, not all of them — put it on the skeleton standing for the region and leave the rest silent.

Every part also accepts the underlying React Native props (ViewProps or TextProps) and a className for Tailwind utilities.

Notes

A placeholder is a picture of content that is not there, so it is hidden from screen readers by default. An unlabelled grey box announces nothing worth hearing, and a screen of them announces it many times over.

Pass label on the one skeleton that stands for the region — the first row of a list, the card standing in for a page — and the wait is announced once, as a busy status. Leave it off the rest.

Under the platform's reduce-motion setting the pulse stops and the placeholder holds at a middle opacity. A skeleton that stops moving still reads as content on its way, because the shape is the message.

Public exports

Values: Skeleton

Types: SkeletonProps

On this page