blur_on

Shimmer

Skeleton placeholder for content loading.

Shimmer Examples

Copy-ready examples with live previews.

Basic text lines

Use different widths to mimic real text rhythm.

Live preview

Basic lines

import Shimmer from "@/packages/ui/src/_components/shimmer/Shimmer";

export default function Example() {
  return (
    <div style={{ display: "grid", gap: 10, maxWidth: 520 }}>
      <Shimmer width="100%" height="16px" />
      <Shimmer width="82%" height="16px" />
      <Shimmer width="64%" height="16px" />
    </div>
  );
}

Card skeleton

Image placeholder + text + multi-line body.

Live preview

Card skeleton

import Shimmer from "@/packages/ui/src/_components/shimmer/Shimmer";

export default function Example() {
  return (
    <div style={{ display: "grid", gap: 12, width: 520, maxWidth: "100%" }}>
      <Shimmer width="100%" height="180px" />
      <Shimmer width="70%" height="20px" />

      <div style={{ display: "grid", gap: 8 }}>
        <Shimmer width="100%" height="14px" />
        <Shimmer width="92%" height="14px" />
        <Shimmer width="86%" height="14px" />
      </div>
    </div>
  );
}

Avatar + text row

Wrap Shimmer to achieve a circular avatar placeholder.

Use a wrapper with `borderRadius` + `overflow: hidden` for circles.

Live preview

Avatar row

import Shimmer from "@/packages/ui/src/_components/shimmer/Shimmer";

export default function Example() {
  return (
    <div style={{ display: "grid", gap: 12, width: 520, maxWidth: "100%" }}>
      <div style={{ display: "flex", gap: 12, alignItems: "center" }}>
        <div style={{ width: 44, height: 44, borderRadius: 999, overflow: "hidden" }}>
          <Shimmer width="44px" height="44px" />
        </div>

        <div style={{ display: "grid", gap: 8, flex: 1, minWidth: 220 }}>
          <Shimmer width="55%" height="14px" />
          <Shimmer width="78%" height="14px" />
        </div>
      </div>
    </div>
  );
}

List rows (repeatable)

Great for feeds, tables, and search results.

Live preview

List skeleton

import Shimmer from "@/packages/ui/src/_components/shimmer/Shimmer";

export default function Example() {
  return (
    <div style={{ display: "grid", gap: 10, width: 520, maxWidth: "100%" }}>
      {Array.from({ length: 6 }).map((_, i) => (
        <div
          key={i}
          style={{
            display: "grid",
            gap: 8,
            padding: "10px 12px",
            border: "1px solid rgba(0,0,0,0.12)",
            borderRadius: 12,
          }}
        >
          <Shimmer width="42%" height="14px" />
          <Shimmer width="86%" height="14px" />
        </div>
      ))}
    </div>
  );
}

Loading state toggle (demo)

Example pattern: show skeletons while loading, render real UI when ready.

Live preview

Toggle loading

import { useState } from "react";
import Shimmer from "@/packages/ui/src/_components/shimmer/Shimmer";
import { Button } from "@/packages/ui/src/_components/buttons_variants/buttons/Button";

export default function Example() {
  const [loading, setLoading] = useState(true);

  return (
    <div style={{ display: "grid", gap: 12, width: 520, maxWidth: "100%" }}>
      <Button variant="primary" onClick={() => setLoading((v) => !v)}>
        Toggle loading
      </Button>

      {loading ? (
        <div style={{ display: "grid", gap: 10 }}>
          <Shimmer width="45%" height="18px" />
          <Shimmer width="100%" height="14px" />
          <Shimmer width="92%" height="14px" />
          <Shimmer width="78%" height="14px" />
        </div>
      ) : (
        <div style={{ display: "grid", gap: 6 }}>
          <div style={{ fontWeight: 700 }}>Loaded content</div>
          <div style={{ opacity: 0.8 }}>Swap this with your real UI when data arrives.</div>
        </div>
      )}
    </div>
  );
}

On this page

Shimmer Props

Shimmer — Props
PropTypeRequiredDefaultDescription
widthstringNoundefinedInline `width` style (e.g. "100%", "320px", "12rem").
heightstringNoundefinedInline `height` style (e.g. "16px", "2.5rem").