Skeleton
Preview: Shimmer
Loading placeholder. Hidden from assistive tech; announce loading on the container instead (aria-busy).
Import
import { Skeleton } from '@marbleui/ui'Props
<Skeleton>
| Prop | Type | Default | Description |
|---|---|---|---|
| animation | 'none' | 'shimmer' | 'pulse' | 'shimmer' | |
| shape | 'circle' | 'rect' | 'text' | 'rect' |
Also accepts HTML element props (278).
Usage notes
Placeholder shaped like content while it loads. For a short wait with no known layout use Spinner; for measurable progress use ProgressBar.
<div role="status" aria-busy="true" aria-label="Loading profile">
<Skeleton shape="circle" className="size-10" />
<Skeleton shape="text" className="w-1/2" />
</div>
Skeletonisaria-hidden. Announce loading on the container, witharia-busyas above, not on each piece.- Size it with
className:shapeisrect(default),circleortext(fixed 14 px height). animationisshimmer(default),pulseornone; both animations are turned off underprefers-reduced-motion.- Match the real layout’s dimensions to avoid layout shift when content arrives.
Example source · show· hide
import { Skeleton } from './skeleton'
const Profile = ({ animation }: { animation: 'shimmer' | 'pulse' }) => (
<div role="status" aria-busy="true" aria-label="Loading profile" className="flex w-80 flex-col gap-4 rounded-xl border border-border bg-surface p-5">
<div className="flex items-center gap-3">
<Skeleton animation={animation} shape="circle" className="size-10" />
<div className="flex flex-1 flex-col gap-2">
<Skeleton animation={animation} shape="text" className="w-1/2" />
<Skeleton animation={animation} shape="text" className="w-1/3" />
</div>
</div>
<Skeleton animation={animation} className="h-32" />
<div className="flex flex-col gap-2">
<Skeleton animation={animation} shape="text" />
<Skeleton animation={animation} shape="text" className="w-4/5" />
</div>
</div>
)
export const styles = {
Shimmer: () => <Profile animation="shimmer" />,
Pulse: () => <Profile animation="pulse" />,
List: () => (
<div role="status" aria-busy="true" aria-label="Loading list" className="flex w-80 flex-col divide-y divide-border rounded-xl border border-border bg-surface">
{Array.from({ length: 4 }, (_, i) => (
<div key={i} className="flex items-center gap-3 p-3">
<Skeleton shape="circle" className="size-8" />
<Skeleton shape="text" className="flex-1" />
<Skeleton className="h-5 w-12 rounded-full" />
</div>
))}
</div>
),
}Source: packages/ui/src/skeleton/skeleton.tsx
Catalog
- Category
- feedback
- Priority
- Foundation
- Primitive
- custom