Skeleton Atom
Shapes for the free-form case, and a matching .Skeleton on every Composition. The second half is
the point: a placeholder built from the same tokens as the real thing cannot drift out of sync with
it, so the page does not jump when data lands.
Shapes
<Skeleton width="12rem" height="1rem" /><Skeleton.Text lines={3} /><Skeleton.Circle size="3rem" />Composition skeletons
{loading ? <Statistic.Skeleton withVisual /> : <Statistic {...stat} />}Do
Reach for the Composition's own .Skeleton, so the placeholder keeps the real layout's size.
Don't
Hand-assemble grey boxes that approximate the card — they will be wrong the first time the card changes.
Props
| Prop | Type | Default | Notes |
|---|---|---|---|
| width / height | string | '100%' / '1rem' | Any CSS length. Prefer rem so it scales with type. |
| radius | 'sm' | 'md' | 'lg' | 'full' | 'md' | Corner token. |
| Skeleton.Text lines | number | 3 | Line count; the last line is short, as real text is. |
| Skeleton.Text lastLineWidth | string | '62%' | Width of that last line. |
| Skeleton.Circle size | string | '2.5rem' | Diameter — for avatars and rings. |
Accessibility and motion
Every shape is aria-hidden, so a screen reader hears the loading state from your live region
rather than from a wall of empty boxes. The shimmer is CSS and stops under
prefers-reduced-motion — the shapes stay, which is what communicates "loading".