Propel

Skeleton

A pulse-animated loading placeholder. Compose a named region with decorative bones sized by CSS lengths.

Show code
import { Skeleton, SkeletonItem } from "@makeplane/propel/components/skeleton";

export default function BasicDemo() {
  return (
    <div className="w-80">
      <Skeleton aria-label="Loading">
        <SkeletonItem blockSize="40px" />
        <SkeletonItem blockSize="40px" inlineSize="60%" />
      </Skeleton>
    </div>
  );
}

Installation

import { Skeleton, SkeletonItem } from "@makeplane/propel/components/skeleton";

Usage

import { Skeleton, SkeletonItem } from "@makeplane/propel/components/skeleton";

export default function BasicDemo() {
  return (
    <div className="w-80">
      <Skeleton aria-label="Loading">
        <SkeletonItem blockSize="40px" />
        <SkeletonItem blockSize="40px" inlineSize="60%" />
      </Skeleton>
    </div>
  );
}

Examples

Stretch

stretch="full" (the default) takes the parent’s inline size; stretch="auto" fits the region to its widest sized bone. A bone is full width unless you pass inlineSize for a percentage or fixed length.

Show code
import { Skeleton, SkeletonItem } from "@makeplane/propel/components/skeleton";

export default function StretchDemo() {
  return (
    <div className="flex w-80 flex-col gap-6">
      <Skeleton aria-label="Full width bars">
        <SkeletonItem blockSize="32px" />
        <SkeletonItem blockSize="32px" />
      </Skeleton>
      <Skeleton aria-label="Fixed width bars" stretch="auto">
        <SkeletonItem blockSize="32px" inlineSize="8rem" />
        <SkeletonItem blockSize="32px" inlineSize="5rem" />
      </Skeleton>
    </div>
  );
}

Layout

layout="stack" (the default) is a column; layout="row" places bones on one line.

Show code
import { Skeleton, SkeletonItem } from "@makeplane/propel/components/skeleton";

export default function LayoutDemo() {
  return (
    <div className="flex w-80 flex-col gap-6">
      <Skeleton aria-label="Stacked bones" layout="stack">
        <SkeletonItem blockSize="32px" />
        <SkeletonItem blockSize="32px" />
        <SkeletonItem blockSize="32px" />
      </Skeleton>
      <Skeleton aria-label="Row of bones" layout="row">
        <SkeletonItem blockSize="32px" />
        <SkeletonItem blockSize="32px" />
        <SkeletonItem blockSize="32px" />
      </Skeleton>
    </div>
  );
}

Circle

variant="circle" is a disc. A lone blockSize is the diameter.

Show code
import { Skeleton, SkeletonItem } from "@makeplane/propel/components/skeleton";

export default function CircleDemo() {
  return (
    <Skeleton aria-label="Loading avatar" stretch="auto" layout="row">
      <SkeletonItem variant="circle" blockSize="40px" />
      <SkeletonItem variant="circle" blockSize="2.5rem" />
    </Skeleton>
  );
}

Fill slot

Size the region with blockSize and omit size on the item so the bone fills the slot. In a region without a blockSize, an unsized bone is one text line tall rather than invisible.

Show code
import { Skeleton, SkeletonItem } from "@makeplane/propel/components/skeleton";

export default function FillSlotDemo() {
  return (
    <div className="w-80">
      <Skeleton aria-label="Loading chart" blockSize="10rem">
        <SkeletonItem />
      </Skeleton>
    </div>
  );
}

API Reference

Skeleton

A pulse-animated loading region that groups placeholder bones. Grafts role="status" onto the styled elements Skeleton and requires an aria-label so the region is never unnamed. Compose SkeletonItem children for the bones. layout and stretch own the region's flex axis and inline size. Exact geometry uses blockSize / inlineSize (not height / width).

PropTypeDefaultDescription
aria-label(required)string—Accessible name for the loading region.
renderReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, {}>—Allows you to replace the component's HTML element with a different tag, or compose it with another component. Accepts a ReactElement or a function that returns the element to render.
layout"stack" | "row""stack"Arrangement of bones: stack is a column, row is a row.
stretch"auto" | "full""full"full takes the parent's inline size; auto is fit-content — the region shrinks to the widest bone that carries an inlineSize. A passed inlineSize overrides both.
blockSizestring—CSS block-size (height) of the loading region, e.g. "10rem" or "160px". Omit to size to the bones inside.
inlineSizestring—CSS inline-size (width) of the loading region, e.g. "8rem". Omit to follow stretch. Passing a length overrides stretch.

SkeletonItem

One decorative placeholder bone. variant="bar" (default) is a rounded-md block; variant="circle" is a disc. Full width unless inlineSize narrows it. Bakes aria-hidden — the enclosing Skeleton names the loading region.

PropTypeDefaultDescription
renderReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, {}>—Allows you to replace the component's HTML element with a different tag, or compose it with another component. Accepts a ReactElement or a function that returns the element to render.
variant"circle" | "bar""bar"Look of the bone: bar is a rounded-md block; circle is a disc.
blockSizestring—CSS block-size (height) of the bone, e.g. "50px", "100%", or "1rem". Omit to fill a region that has a blockSize; in a region without one the bone is one text line tall (16px). On variant="circle", a lone blockSize is also the inline size (square).
inlineSizestring—CSS inline-size (width) of the bone, e.g. "70px" or "60%". Omit for the parent's full inline size.