Components / Feedback

Skeleton

Reserve space while content is still loading.

Install

npx shadcn@latest add https://irisui.dev/r/skeleton.json
import { Skeleton } from "@/components/iris/skeleton/skeleton";
Registry item skeletonBrings in foundationRegistry JSON

Preview

Skeleton

Placeholder lines (and an optional avatar circle) that reserve space while content loads, then crossfade into it.

When to use

  • First load of cards, list rows, and profiles whose layout is known in advance.
  • Swapping a placeholder for real content without a layout jump, by wrapping the content as children.
  • Not for tasks with measurable progress: use Progress. Not for agent "thinking" states: use LoadingState or Shimmer.

Usage

import { Skeleton } from "@/components/iris/skeleton/skeleton";

h(Skeleton, { avatar: true, lines: 2, label: "Loading profile" });

// Crossfade into content when it arrives
h(Skeleton, { avatar: true, lines: 2, loading: !profile }, profile && h(ProfileRow, profile));

Props

Prop Type Default Description
label string "Loading content" Accessible name announced while loading.
lines number 3 Number of text lines.
avatar boolean false Adds a leading circle.
children ReactNode — Content to reveal once loading finishes.
loading boolean true Keeps the placeholder while true. Only used with children.
className string — Extra class on the wrapper.

Notes

  • The placeholder is an <output> (implicit role="status") region with aria-busy and the label; the bars themselves are hidden from assistive tech.
  • Lines pulse in a short stagger and settle after about 20 seconds (11 cycles), so a stuck load does not flicker forever. The pulse and crossfade are removed under reduced motion.
  • Reads --surface, --line-strong, --radius-control, --control-height-md.