Bloom Logo

Skeleton

Placeholder loading indicator with a pulse animation. Useful for mimicking content layout while data is being fetched.

skeleton.tsx

Skeleton loader component supporting circle, rectangle, and text variants with design tokens and accessibility.

ReactTailwindUI ComponentLoading
"use client";

import * as React from "react";
import { cn } from "@/lib/utils";
import { designRadius } from "@/lib/design-system";

export interface SkeletonProps extends React.HTMLAttributes<HTMLDivElement> {
  variant?: "circle" | "rectangle" | "text";
  radius?: keyof typeof designRadius;
  isLoaded?: boolean;
}

const variantStyles = {
  circle: "rounded-full aspect-square",
  rectangle: "",
  text: "h-4 w-full rounded-md",
};

const Skeleton = React.forwardRef<HTMLDivElement, SkeletonProps>(
  (
    {
      className,
      variant = "rectangle",
      radius = "lg",
      isLoaded = false,
      children,
      ...props
    },
    ref
  ) => {
    if (isLoaded) {
      return <>{children}</>;
    }

    return (
      <div
        ref={ref}
        role="status"
        aria-busy="true"
        aria-label="Loading..."
        className={cn(
          "animate-pulse bg-muted/70 shrink-0",
          variantStyles[variant],
          variant !== "circle" && designRadius[radius],
          className
        )}
        {...props}
      >
        <span className="sr-only">Loading...</span>
      </div>
    );
  }
);

Skeleton.displayName = "Skeleton";

export { Skeleton };

Variants

Choose between rectangle, circle, or text variants.

variant: circle | rectangle | text
Loading...
Loading...
Loading...
Loading...

Complex Layout Pattern

Combine multiple Skeleton elements to compose card placeholders.

Loading...
Loading...
Loading...
Loading...
Loading...
Loading...

Loaded State Toggle

When isLoaded becomes true, the Skeleton renders its children directly.

isLoaded: boolean
Content loaded successfully!
API Reference

Props — Skeleton

Properties for configuring the Skeleton loader component.

PropTypeDefaultDescription
variant'circle' | 'rectangle' | 'text''rectangle'Shape style of the skeleton placeholder.
radius'none' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | 'full''lg'Corner rounding scale (not applicable to 'circle').
isLoadedbooleanfalseWhen true, replaces the skeleton placeholder with children nodes.