Skeleton component
Skeleton is a loading placeholder — either a standalone shaped block or a wrapper that renders its skeleton until `isLoaded` flips, then reveals the real content.
Playground
Change a prop on the right and the preview updates. Switch to Code to copy what you see.
Recipes
Copy-paste patterns for the ways Skeleton actually gets used — each one a real, self-contained example.
Shapes
Three primitive shapes — text, rect, and circle — sized with width/height to match whatever they stand in for.
<Skeleton variant="circle" width={40} height={40} />
<Skeleton variant="rect" width={200} height={120} />
<Skeleton variant="text" width={160} />Multi-line text
variant="text" with lines renders a stack of text placeholders — the last line comes up short, like a real paragraph.
<Skeleton variant="text" lines={3} />Wrap until loaded
Wrap real content and flip isLoaded when data arrives — Skeleton shows the placeholder, then reveals the children in place with no layout shift.
<Skeleton isLoaded={!loading}>
<Avatar src={user.avatar} name={user.name} />
</Skeleton>Composed card skeleton
Compose the primitives to mirror a real card's layout so the loading state has the same shape as the content it replaces.
<div className="flex gap-3">
<Skeleton variant="circle" width={44} height={44} />
<div className="flex-1">
<Skeleton variant="text" width="60%" />
<Skeleton variant="text" lines={2} />
</div>
</div>Example
<Skeleton isLoaded={!loading}>
<Avatar src={user.avatar} name={user.name} />
</Skeleton>
<Skeleton className="h-4 w-40" />Props
The full public API for Skeleton. Every prop is stable and intentionally typed.
Appearance
| Prop | Type | Default | Description |
|---|---|---|---|
| variant | "text" | "rect" | "circle" | rect | Shape of a standalone placeholder. |
| width | number | string | — | CSS length (number → px). |
| height | number | string | — | CSS length (number → px). |
| radius | OksRadius | — | Corner radius override. |
variant
"text" | "rect" | "circle"
default: rect
Shape of a standalone placeholder.
width
number | string
default: —
CSS length (number → px).
height
number | string
default: —
CSS length (number → px).
radius
OksRadius
default: —
Corner radius override.
Content
| Prop | Type | Default | Description |
|---|---|---|---|
| lines | number | — | variant="text" only — stacked lines, last one shorter. |
| children | ReactNode | — | Wrapper-mode content, hidden behind the placeholder until isLoaded. |
lines
number
default: —
variant="text" only — stacked lines, last one shorter.
children
ReactNode
default: —
Wrapper-mode content, hidden behind the placeholder until isLoaded.
Behavior & states
| Prop | Type | Default | Description |
|---|---|---|---|
| isLoaded | boolean | false | Wrapper mode — reveal children when true. |
isLoaded
boolean
default: false
Wrapper mode — reveal children when true.
Styling
| Prop | Type | Default | Description |
|---|---|---|---|
| classNames | { base?: string } | — | Slot class overrides. |
classNames
{ base?: string }
default: —
Slot class overrides.
Accessibility
- While loading, the region is marked `aria-busy="true"` so assistive tech knows content is pending.
- The shimmer animation respects `prefers-reduced-motion` and falls back to a static tint.