Skeleton
The shape of what has not arrived yet.
Overview
The shape of what has not arrived yet.
First example
<Skeleton width={140} height={20} /><Skeleton width={48} height={48} radius="full" />
Anatomy
<Skeleton />
One node and no slots. A placeholder is a rectangle; there is nothing inside it to
name. A paragraph of them is three of these in a Column — composition doing what a
lines={3} prop would otherwise hard-code, including the last line being shorter, which is
the only reason the paragraph reads as a paragraph.
Usage
A block, sized by the caller:
<Skeleton width={140} height={20} />
<Skeleton width={48} height={48} radius="full" />
A paragraph:
<Column gap={8}>
<Skeleton height={12} />
<Skeleton height={12} />
<Skeleton height={12} width="60%" />
</Column>
As a gate, which is what isLoading is for:
<Skeleton isLoading={!user} height={20} width={140}>
<Typography>{user?.name}</Typography>
</Skeleton>
A row of one, mirroring the layout it stands in for:
<Row gap={12} alignItems="center">
<Skeleton width={40} height={40} radius="full" />
<Column gap={6} flex={1}>
<Skeleton height={12} width="50%" />
<Skeleton height={12} width="80%" />
</Column>
</Row>
Root props
SkeletonProps
The node's inherited React Native props apply too, and so do its style props — padding, margin, width and the rest.
| Prop | Type | Required | Description |
|---|---|---|---|
| children | ReactNode | No | What the block stands in for, rendered once `isLoading` is `false`. A skeleton with no children is a block that never resolves, which is the right thing for a placeholder whose content is mounted elsewhere. |
| radius | RadiusKey | undefined | No | The corner. `full` is the circle an avatar placeholder needs, and it is why this is a prop rather than the caller's `borderRadius` — a circle is a shape the vocabulary names, and it has to survive a theme redrawing every corner in the library. |
| color | string | undefined | No | A raw tint (`'#7c3aed'`), never a token (R7). There is one thing to colour on a block, so it lands on the block. |
| isLoading | boolean | undefined | No | `false` swaps the block for `children`. It is the prop that makes the component a gate rather than a shape you mount and unmount around your own content: ```tsx <Skeleton isLoading={!user} height={20} width={140}> <Typography>{user?.name}</Typography> </Skeleton> ``` |
| animation | boolean | undefined | No | `false` freezes the block at full opacity and mounts no worklet. A boolean rather than the reference implementation's `'shimmer' | 'pulse' | 'none'`: a shimmer is a gradient sweeping across the block, a gradient needs `react-native-svg`, and that is an optional peer a component in the core cannot require. One animation, so there is nothing for a name to choose between. |
| style | StyleProp<ViewStyle> | No | — |
Slots
Variants, sizes and colour
Accessibility
accessibilityElementsHidden and importantForAccessibility="no-hide-descendants" are
set. A block stands in for content that is not there; announcing its absence is busy on
whatever region is loading, not a stop on each rectangle. Both stay overridable (R9).
Migration from legacy
| Legacy | v1 |
|---|---|
<Skeleton width={140} height={20}/> | <Skeleton width={140} height={20} /> |
<Skeleton circle size={40} /> | <Skeleton width={40} height={40} radius="full" /> |
<Skeleton lines={3} /> | three <Skeleton> in a <Column> |
<Skeleton animated={false} /> | <Skeleton animation={false} /> |
Implementation notes
Animation
One pulse: the block breathes between full opacity and a half, a second each way, eased in
and out. animation={false} freezes it at full and mounts no worklet — the branch renders
a plain View, so a long list frozen for a screenshot costs nothing.
No shimmer, where the reference implementation's default is one. A shimmer is a gradient sweeping across the
block; a gradient needs react-native-svg, and that is an optional peer a component in the
fifteen-component core cannot require. One animation, so there is nothing for a name to
choose between — animation is a boolean rather than the reference implementation's
'shimmer' | 'pulse' | 'none'.