Skip to Content

Skeleton

Skeleton loading mitigates the wait by providing a perceived sense of movement and activity. It puts the user’s focus on what is loading. The package exposes a default skeleton for simple body text plus Skeleton.Text and Skeleton.Shape for structured placeholders.

Loading...

Overview

Resources

Loading...

Loading...

Loading...

Loading...

Install

yarn add @camp/skeleton

Upgrading to Next Gen

The Skeleton component is published as @camp/skeleton (replacing @activecampaign/camp-components-skeleton).

🧩 Compound API: Use Skeleton.Text for typography-shaped placeholders (body, heading, eyebrow) and Skeleton.Shape for rectangles, squares, and circles (images, avatars, rows).

🎨 Layout-aware props: Text supports lines, randomizeWidth, textAlign, and width percentages. Shape supports repeat for lists of placeholders and maxWidth / height / borderRadius for layout control.

🔆 Styling: Skeleton continues to use Camp’s styled layer so it matches surrounding typography and surfaces when your app provides the usual Camp / styled-components setup.

Migration steps

  1. Remove @activecampaign/camp-components-skeleton and install @camp/skeleton.
  2. Keep default usage as import Skeleton from '@camp/skeleton' — the default export renders body-style text, same as before.
  3. Prefer Skeleton.Text and Skeleton.Shape where you need explicit appearances (see Variations).

Variations

Playground (Composite)

Combined heading text, multi-line body, and a rectangular shape — useful as a reference layout.

import Skeleton from '@camp/skeleton'; <> <Skeleton.Text appearance="heading" size="large" /> <Skeleton.Text appearance="body" size="small" lines={3} randomizeWidth /> <Skeleton.Shape appearance="rectangle" maxWidth="100%" /> </>;

Text (Multiple Lines)

Use lines to mimic paragraphs; pair with randomizeWidth so each line width varies naturally.

import Skeleton from '@camp/skeleton'; <Skeleton.Text appearance="body" size="small" lines={4} />;

Shape (Circle)

Use appearance="circle" with maxWidth for avatars or icon placeholders; use repeat for a row of items.

import Skeleton from '@camp/skeleton'; <Skeleton.Shape appearance="circle" maxWidth="80px" />;

Card Layout

Combine Skeleton.Shape and Skeleton.Text to mirror card content (media area, title, body).

import Skeleton from '@camp/skeleton'; <div style={{ maxWidth: 400, display: 'flex', flexDirection: 'column', gap: 12 }}> <Skeleton.Shape appearance="rectangle" maxWidth="100%" /> <Skeleton.Text appearance="heading" size="medium" maxWidthPercentage={60} /> <Skeleton.Text appearance="body" size="small" lines={3} randomizeWidth /> </div>;

Usage

Best practices

  • Use skeletons when content structure is predictable but data or media is still loading, so layout does not jump when the real UI appears.
  • Combine with the loading indicator when you need a compact spinner for a control or indeterminate inline wait rather than a full content block.
  • Avoid showing skeleton flash for very fast requests (under roughly 400ms) where it can feel noisy.

Content guidelines

✅ DO

  • Match appearance and size on Skeleton.Text to the real text styles that will replace them.

  • Use Skeleton.Shape with repeat for grids or lists of similar items (e.g. avatar rows).

  • Use randomizeWidth on multi-line body placeholders so lines do not look unnaturally identical.

🚫 DON’T

  • Don’t rely on skeleton copy as real content — always swap to live content when data is ready.

  • Don’t stack unrelated skeleton blocks without spacing; mirror the final layout’s rhythm.

  • Don’t use skeleton states where a simple loading indicator is clearer (tiny controls, icon-only actions).

Accessibility

Skeleton placeholders are non-interactive and implemented as styled blocks (no role or focus). They are intended as visual stand-ins while content loads.

  • Keyboard: No keyboard behavior — skeletons do not receive focus.
  • Screen readers: Treat skeleton UI as decorative relative to the eventual content. Prefer aria-busy="true" on the loading region (or an equivalent pattern) while content is loading, and ensure that when real content mounts, status updates are conveyed appropriately (e.g. aria-live on meaningful summaries where your product pattern requires it).
  • Invalid props: If minWidthPercentage is greater than maxWidthPercentage, Skeleton.Text renders nothing and logs an error — fix percentages to avoid silent blank UI.

Similar components

Loading Indicator

Loading Indicator

Provides visual feedback for processes that take a noticeable amount of time to complete.

Text

Text

Used to display text in UI, supports various styles and options.

Last updated on