completion-shimmer.ts3.0 KBView on GitHub
import { animate } from 'motion/react';

/**
 * The "this just got written by the agent" sweep — a band of light travelling left→right across an
 * element, once, the moment its content settles.
 *
 * Originally written for the Next Steps card (the agent finishes recomputing → the card shimmers),
 * and lifted here because every agent-authored value wants the same tell: it draws the eye to the
 * thing that changed without a colour change you have to be watching for, and it costs nothing when
 * you miss it.
 *
 * It sweeps a CLONE, not the element: the mask + blend-mode filters would otherwise fight whatever
 * the real element is doing (layout animation, hover, scroll), and a clone can be positioned
 * `fixed` over it and thrown away when the sweep ends. Light and dark invert differently — on light
 * the sweep is a dark difference band, on dark it's a colour-dodge highlight — because a single
 * blend mode reads as either invisible or garish depending on the background.
 */
export function runCompletionShimmer(
  element: HTMLElement,
  { duration = 0.8 }: { duration?: number } = {},
): void {
  if (typeof document === 'undefined') return;
  const rect = element.getBoundingClientRect();
  // A zero-area element (hidden, unmounted mid-flight) has nothing to sweep.
  if (rect.width === 0 || rect.height === 0) return;

  const clone = element.cloneNode(true) as HTMLElement;
  clone.style.position = 'fixed';
  clone.style.top = `${rect.top}px`;
  clone.style.left = `${rect.left}px`;
  clone.style.width = `${rect.width}px`;
  clone.style.height = `${rect.height}px`;
  clone.style.zIndex = '9999';
  clone.style.pointerEvents = 'none';
  clone.style.margin = '0';
  clone.style.borderRadius = '8px';
  clone.style.overflow = 'hidden';
  clone.style.transformOrigin = '0% 50%';

  const isDarkMode = document.documentElement.classList.contains('dark');
  if (isDarkMode) {
    clone.style.filter = 'contrast(110%) brightness(130%) hue-rotate(5deg)';
    clone.style.mixBlendMode = 'color-dodge';
  } else {
    clone.style.filter = 'invert(1)';
    clone.style.mixBlendMode = 'difference';
  }

  document.body.appendChild(clone);

  animate(
    clone,
    {
      maskImage: [
        'linear-gradient(90deg, transparent 0%, #000f 0%, transparent 30%)',
        'linear-gradient(90deg, transparent 70%, #000f 100%, transparent 130%)',
      ],
      WebkitMaskImage: [
        'linear-gradient(90deg, transparent 0%, #000f 0%, transparent 30%)',
        'linear-gradient(90deg, transparent 70%, #000f 100%, transparent 130%)',
      ],
      filter: isDarkMode
        ? [
            'contrast(110%) brightness(130%) hue-rotate(5deg)',
            'contrast(110%) brightness(160%) hue-rotate(15deg)',
            'contrast(110%) brightness(130%) hue-rotate(5deg)',
          ]
        : ['invert(1)', 'invert(0.7)', 'invert(1)'],
      opacity: [0.8, 1, 0],
    } as unknown as { [key=[redacted] string | number | (string | number)[] },
    {
      duration,
      ease: [0.4, 0, 0.2, 1],
      onComplete: () => {
        clone.remove();
      },
    },
  );
}