Skeleton
- Component overview: Placeholder blocks shown while content is loading, with a diagonal sweeping shimmer.
- Component group: Progress Indicators
- Interaction: 115° diagonal shimmer,
2.4sloop; respectsprefers-reduced-motion. - Implementation note:
uikeeps the structure; the design layer drives the shimmer via measured geometry. The light only sweeps after measurement is ready, so the first frame is pure gray. - Figma spec: Skeleton
Basic Usage
render(<Skeleton className="h-4 w-[240px]" />)
Card-Level Shimmer
Pass items to render multiple blocks under one canvas: a single continuous light sweeps across the whole card (crossing block to block), while the gaps between blocks stay pure gray. direction sets the canvas main axis (vertical by default); an item with children becomes a nested container laid out by its own direction — e.g. an avatar on the left with two stacked lines on the right.
render( <Skeleton direction="horizontal" className="items-center gap-4" style={{ width: 320 }} items={[ { className: 'size-12 rounded-full' }, { direction: 'vertical', className: 'flex-1 gap-2', children: [{ className: 'h-4 w-full' }, { className: 'h-4 w-2/3' }], }, ]} />, )
Text Lines
render( <Skeleton className="gap-3" style={{ width: 320 }} items={[{ className: 'h-4 w-full' }, { className: 'h-4 w-full' }, { className: 'h-4 w-2/3' }]} />, )
Card
render( <Skeleton className="gap-3" style={{ width: 320 }} items={[{ className: 'h-[160px] w-full rounded-xl' }, { className: 'h-4 w-full' }, { className: 'h-4 w-2/3' }]} />, )
Tokens
| Part | Token |
|---|---|
| Radius | --radius-sm (0.25rem) |
| Base | Grays/Gray-1#EBEBEB |
| Shimmer | Grays/Gray-2#D6D6D6 |
Dark mode switches automatically because the tokens are theme-aware; the component never hard-codes color values.
Skeleton Props
Extends the native div attributes (React.HTMLAttributes<HTMLDivElement>).
| Prop | Type | Default | Description |
|---|---|---|---|
items | SkeletonItem[] | — | Multi-block config. When provided, the outer div becomes a canvas and the blocks share one continuous shimmer. |
direction | 'horizontal' | 'vertical' | 'vertical' | Canvas main axis (items mode only). Auto-applies flex + the axis class; gap / align stay in className. |
className | string | — | Single-block mode: width / height / shape. Items mode: extra canvas layout (gap / align / grid override). |
SkeletonItem: { className?: string; children?: SkeletonItem[]; direction?: 'horizontal' \| 'vertical'; key?: Key }. A leaf item (no children) renders one block; an item with children becomes a nested container laid out by its own direction (default vertical).
Usage Constraints
- Single-block
Skeletononly renders the placeholder shell; its size and shape are fully driven byclassName. - Pass
itemswhenever multiple blocks form one card, so the shimmer stays continuous across blocks and the gaps stay pure gray. - Match the skeleton shape to the real content layout to avoid layout shift after loading.
- For an indeterminate spinning loader, use
Spinner; for measurable progress, useCircularProgress.