Yugen UI

Skeleton presets

Ready-made skeletons for paragraphs, avatars, cards, lists and tables, with the size, radius and spacing of the real components.

The presets are built on SkeletonItem and inherit animation (wave / pulse) and appearance (opaque / translucent). On its own, each preset is a Skeleton (role="progressbar", aria-busy); nested presets don't repeat the announcement for screen readers. Use them as the skeleton prop of AsyncContent.
Yugen Labs · experimentalThis component is outside SemVer: its API can change in a minor release, and What's new says so. Versioning policy

Import

Install from npm, copy the source into your project with @yugen-ui/cli or the shadcn CLI, or import directly when working in this repo.

TSX
// npm install yugen-uiimport { SkeletonText, SkeletonAvatar, SkeletonCard, SkeletonList, SkeletonTable } from "yugen-ui";

Variants

Each tile is a standalone example: hover to copy, or press Code to see the source.

SkeletonText

lines sets the number of lines, with a shorter last line; size small 12 · medium 16 · large 20px.

SkeletonAvatar

Use the same size as the Avatar it stands in for.

SkeletonTable

rows × columns, with 44px rows like Table size medium.

Hana Sato
2 hours ago

Spring in Kyoto

The cherry trees along the Philosopher's Path are in full bloom. Go early in the morning.

Skeleton that matches the real content

SkeletonCard with header + 2 lines + 2 buttons lines up exactly with the Card below, so nothing shifts when they swap.

Usage

Do
  • Match the real layout: same number of columns, avatar size, line height and button position.
  • Only sketch the parts that will definitely be there; keep the line count close to typical data.
  • Use translucent on colored surfaces, and pulse when wave is distracting.
Don't
  • Don't draw skeletons for content that is already available (page title, static labels).
  • Don't use skeletons for actions under 300ms. Leave that to AsyncContent / useSpinDelay.
  • Don't put a Spinner in the middle of a skeleton.

Props

Prop · TypeDefaultDescription
SkeletonText.lines / sizenumber · "small" | "medium" | "large"Default: 3 · "medium"Number of lines (the last one at 60%) and line height.
SkeletonAvatar.size / shapeSkeletonItemSize · "circular" | "square"Default: 32 · "circular"Side length (px) and shape.
SkeletonCard.header / media / lines / actionsboolean · boolean · number · numberDefault: false · true · 2 · 2Parts of the card.
SkeletonList.rows / avatarSize / avatarShapenumber · SkeletonItemSize · "circular" | "square"Default: 3 · 40 · "circular"Number of rows and the avatar in each row.
SkeletonTable.rows / columns / headernumber · number · booleanDefault: 5 · 4 · trueTable dimensions.
animation / appearance"wave" | "pulse" · "opaque" | "translucent"Default: "wave" · "opaque"Same as Skeleton; nested presets inherit from the outer preset.

Messages

Text built into the component: labels, aria-labels, screen reader announcements.

English by default. Change it with the messages prop of YugenProvider, by the namespace below; messagesVi has the Vietnamese set. See Interface language.

messages.skeleton

Key · TypeDefault (English)messagesVi
labelstring

aria-label của vùng đang tải (role="progressbar").

Default (English)"Loading content"messagesVi"Đang tải nội dung"