Skeleton

Decorative placeholders with rectangle, text, and media shapes.

import { Skeleton } from 'ui-lab-components/skeleton';
 
export function Example() {
  return (
    <section aria-busy="true" aria-label="Loading profile" data-skeleton-animate>
      <Skeleton.Image w="100%" ratio="16/9" />
      <Skeleton.Text size="body" lines={3} />
      <Skeleton w={96} h={28} />
    </section>
  );
}

skeleton/01-skeleton-rectangles

The default rectangle alongside an explicit numeric width and height.

Loading interactive preview
import { Skeleton } from 'ui-lab-components/skeleton';
 
export const metadata = {
  title: 'Rectangle Geometry',
  description: 'The default rectangle alongside an explicit numeric width and height.',
  access: 'free' as const,
};
 
export default function Example() {
  return (
    <div className="flex flex-col gap-4">
      <Skeleton />
      <Skeleton w={180} h={20} />
    </div>
  );
}
 

skeleton/02-skeleton-paragraph

A four-line body placeholder with a natural shorter final row.

Loading interactive preview
import { Skeleton } from 'ui-lab-components/skeleton';
 
export const metadata = {
  title: 'Paragraph Rows',
  description: 'A four-line body placeholder with a natural shorter final row.',
  access: 'free' as const,
};
 
export default function Example() {
  return <Skeleton.Text lines={4} lastLineWidth="70%" w={320} />;
}
 

skeleton/03-skeleton-height-derived

Numeric total height deterministically chooses how many complete text rows fit.

Loading interactive preview
import { Skeleton } from 'ui-lab-components/skeleton';
 
export const metadata = {
  title: 'Height-Derived Rows',
  description: 'Numeric total height deterministically chooses how many complete text rows fit.',
  access: 'free' as const,
};
 
export default function Example() {
  return <Skeleton.Text h={200} w={320} />;
}
 

skeleton/04-skeleton-semantic-sizes

One-line heading and display placeholders use semantic row geometry.

Loading interactive preview
import { Skeleton } from 'ui-lab-components/skeleton';
 
export const metadata = {
  title: 'Semantic Text Sizes',
  description: 'One-line heading and display placeholders use semantic row geometry.',
  access: 'free' as const,
};
 
export default function Example() {
  return (
    <div className="flex flex-col gap-5">
      <Skeleton.Text size="heading" w={150} />
      <Skeleton.Text size="display" w={240} />
      <Skeleton.Text size="heading" scale={1.25} w={180} />
    </div>
  );
}
 

skeleton/05-skeleton-image

A media placeholder using width and aspect ratio instead of image semantics.

Loading interactive preview
import { Skeleton } from 'ui-lab-components/skeleton';
 
export const metadata = {
  title: 'Image Ratio',
  description: 'A media placeholder using width and aspect ratio instead of image semantics.',
  access: 'free' as const,
};
 
export default function Example() {
  return <Skeleton.Image w={320} ratio="16/9" />;
}
 

skeleton/06-skeleton-article

One accessible, animated region composes image, heading, metadata, and body placeholders.

Loading interactive preview
import { Skeleton } from 'ui-lab-components/skeleton';
 
export const metadata = {
  title: 'Accessible Article Loading State',
  description: 'One accessible, animated region composes image, heading, metadata, and body placeholders.',
  access: 'free' as const,
};
 
export default function Example() {
  return (
    <article
      aria-busy="true"
      aria-label="Loading article"
      data-skeleton-animate
      className="flex w-full max-w-md flex-col gap-5"
    >
      <Skeleton.Image w="100%" ratio="16/9" />
      <div className="flex items-center gap-3">
        <Skeleton w={36} h={36} className="rounded-full" />
        <Skeleton.Text lines={2} w={140} scale={0.75} />
      </div>
      <Skeleton.Text size="heading" w="82%" />
      <Skeleton.Text lines={4} />
    </article>
  );
}
 
UI Lab