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();
},
},
);
}