Skip to content
Black FridayBlack Friday launch price: Lifetime $149 until 30 Nov. Regular price $299 from 1 Dec.ends in 15d 03:13:36Get Lifetime →
loopkit
proNew273 lines · framer-motion

Loader Skeleton Shimmer

A wait that reads as progress, not a stall. A full-width showcase section for a skeleton-loading pattern: a sample card with avatar, thumbnail and text-line placeholders swept by a looping shimmer, with a toggle to cross-fade into the loaded version of the same card.

Use it for
Marketing or docs pages that want to demonstrate a product's loading state, or as a reference block to copy the shimmer pattern from into real list/card UIs.
Themes
Light + dark
License
Commercial use
Live
Loaders

A skeleton that feels like progress

Each shape mirrors the real content's layout, with a soft shimmer sweep so the wait reads as motion, not a stall.

tsx
"use client";

import * as React from "react";
import { motion, AnimatePresence, useReducedMotion } from "framer-motion";
import { cn } from "@/lib/utils";

function useReducedMotionSafe() {
  const prefersReduced = useReducedMotion();
  const [mounted, setMounted] = React.useState(false);
  React.useEffect(() => setMounted(true), []);
  return mounted ? !!prefersReduced : false;
}

/**
 * Full-width showcase section for a skeleton-loading pattern: a sample card
 * with avatar / text-line / thumbnail placeholders animated with a looping
 * shimmer sweep, plus a toggle to cross-fade into a "loaded" version of the
 * same card. The shimmer loops continuously while the section is visible and
 * the tab is active, and sits still under prefers-reduced-motion.
 */

export interface LoaderSkeletonShimmerProps {

The rest is in Pro.

Full source, the rebuild prompt and registry install unlock with Pro or Lifetime.

Get Pro

How it behaves

  • →Each placeholder (avatar circle, thumbnail block, text lines) is swept by a moving linear-gradient highlight band on a background-position CSS keyframe loop, using design tokens so the sweep reads correctly in both themes.
  • →'Show loaded state' swaps the skeleton card for a populated version of the same layout with generic, non-personal sample content, cross-fading with framer-motion AnimatePresence.
  • →Replay bumps a key on the card to remount the shimmer loop from its start.
  • →The shimmer loop pauses via IntersectionObserver when the section scrolls offscreen and via a visibilitychange listener when the tab is hidden.
  • →rows sets how many text-line placeholders render, shimmerSpeed sets the sweep duration, radius sets corner rounding on the card and every placeholder, showAvatar toggles the avatar circle.
  • →Under prefers-reduced-motion, placeholders render as still blocks with no sweep; the Replay and state toggle still work on demand.

Accessibility

  • ✓The skeleton card is `role="status"` with an `aria-label` announcing that content is loading.
  • ✓Decorative sweep layers and the loaded-state thumbnail are `aria-hidden`; only real text is exposed to the accessibility tree.
  • ✓Replay and the state toggle are real `<button>` elements, the toggle exposes `aria-pressed`, both reachable and operable by keyboard.
  • ✓Honours prefers-reduced-motion.