# Shimmer Effect

The ShimmerEffect component creates a shimmering animation, ideal for loading placeholders or skeleton screens.

- **Category:** Component
- **Docs:** https://uibeats.com/docs/component/shimmer-effect
- **Registry:** https://uibeats.com/r/shimmer-effect.json
- **License:** MIT
- **npm dependencies:** `motion`

## Installation

```bash
npx shadcn@latest add https://uibeats.com/r/shimmer-effect.json
```

Or install the dependencies and copy the source below:

```bash
npm install motion
```

## When to use

Use for loading states shaped like the content that will replace them. A placeholder that matches the final layout feels faster than a spinner because nothing shifts when the data arrives.

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `width` | `string \| number` | `'100%'` | Width of the shimmer effect |
| `height` | `string \| number` | `'1rem'` | Height of the shimmer effect |
| `borderRadius` | `string \| number` | `'0.375rem'` | Border radius of the shimmer effect |
| `duration` | `number` | `1.5` | Duration of one shimmer animation cycle (in seconds) |
| `className` | `string` | `''` | Additional CSS classes for styling |

## Example usage

```tsx
import React from "react";
import ShimmerEffect from "@/components/demo/component/shimmer-effect";

const ShimmerEffectUsage = () => {
  return <ShimmerEffect width="200px" height="20px" duration={2} />;
};

export default ShimmerEffectUsage;
```

## Source

Save as `components/ui/shimmer-effect.tsx`.

```tsx
"use client";

import { motion, useReducedMotion } from "motion/react";

interface ShimmerEffectProps {
  width?: string | number;
  height?: string | number;
  borderRadius?: string | number;
  /** Seconds for one sweep. */
  duration?: number;
  className?: string;
}

/**
 * A loading placeholder with a sweeping highlight.
 *
 * Both colours are derived from `currentColor`, so the placeholder works on a
 * dark surface as well as a light one. The original hardcoded a black base and
 * a white sweep, which disappeared entirely in dark mode.
 */
export function ShimmerEffect({
  width = "100%",
  height = "1rem",
  borderRadius = "0.375rem",
  duration = 1.5,
  className = "",
}: ShimmerEffectProps) {
  const prefersReducedMotion = useReducedMotion();

  return (
    <div
      style={{ width, height, borderRadius }}
      className={`relative overflow-hidden bg-current/10 ${className}`}
      aria-hidden="true"
    >
      {prefersReducedMotion ? null : (
        <motion.div
          className="size-full"
          style={{
            background:
              "linear-gradient(90deg, transparent 0%, currentColor 50%, transparent 100%)",
            opacity: 0.18,
          }}
          animate={{ x: ["-100%", "100%"] }}
          transition={{ repeat: Infinity, duration, ease: "linear" }}
        />
      )}
    </div>
  );
}

export default ShimmerEffect;
```

## Credits

Written by [Michael](https://github.com/lappemic).
