implement
Skeleton

Skeleton

A shape standing in for content that has not arrived.

import { Div } from "@implementjs/core";
import { Skeleton } from "@/lib/components/ui/skeleton";

export default function SkeletonDemo() {
	return Div(
		{ class: "flex w-full max-w-sm items-center gap-4" },
		Skeleton({ class: "size-12 shrink-0 rounded-full" }),
		Div(
			{ class: "flex flex-1 flex-col gap-2" },
			Skeleton({ class: "h-4 w-full" }),
			Skeleton({ class: "h-4 w-2/3" }),
		),
	);
}

Installation

npx jsrepo add @implementjs/ui/skeleton

Nothing else comes with it — this one stands alone on @implementjs/core and @implementjs/primitives.

Usage

import { Skeleton } from "@/lib/components/ui/skeleton";

Skeleton({ class: "h-4 w-48" });
Skeleton({ class: "size-12 rounded-full" });

There are no size props: give it the classes the real content will have, so the swap does not move the layout.

Matching the real thing

A skeleton is worth having only if it is the same size as what replaces it. Build it from the same classes:

// the real row
Div({ class: "flex items-center gap-4" }, Avatar({ class: "size-12" }), Span("Aidan Bleser"));

// its placeholder
Div(
	{ class: "flex items-center gap-4" },
	Skeleton({ class: "size-12 rounded-full" }),
	Skeleton({ class: "h-4 w-32" }),
);

Reduced motion

The pulse is turned off under prefers-reduced-motion — the shape stays, the animation goes.

API Reference

Skeleton

A shape standing in for content that has not arrived. Size it with the classes the real content will have, so the swap does not move the layout. Renders a Div; extra props are forwarded onto it.