uniquel
componentbouncing-dots-overlaysource: ok · hit
Bouncing Dots Overlay
A light three-dot loading overlay with staggered motion.
npx shadcn add "https://uniquel.io/r/bouncing-dots-overlay.json"free
Visual style
3d
Tags auto-generated by rules on 9/24/2026 — empty means no evidence, not lack of support.
Files1 · source cached 10/9/2026, 12:22:30 AM
components/overlay-loaders/BouncingDotsOverlay.tsx
"use client";
import { useEffect } from "react";
type BouncingDotsOverlayProps = {
open: boolean;
onOpenChange?: (open: boolean) => void;
label?: string;
className?: string;
};
export default function BouncingDotsOverlay({
open,
onOpenChange,
label = "Loading",
className = "",
}: BouncingDotsOverlayProps) {
useEffect(() => {
if (!open) return;
const overflow = document.body.style.overflow;
const closeOnEscape = (event: KeyboardEvent) => {
if (event.key === "Escape") onOpenChange?.(false);
};
document.body.style.overflow = "hidden";
window.addEventListener("keydown", closeOnEscape);
return () => {
document.body.style.overflow = overflow;
window.removeEventListener("keydown", closeOnEscape);
};
}, [onOpenChange, open]);
if (!open) return null;
return (
<div
role="status"
aria-live="polite"
className={[
"fixed inset-0 z-50 grid place-items-center bg-slate-950/50 backdrop-blur-sm",
className,
]
.filter(Boolean)
.join(" ")}
>
<div className="flex items-center gap-3" aria-hidden>
<span className="h-3 w-3 animate-bounce rounded-full bg-white" />
<span
className="h-3 w-3 animate-bounce rounded-full bg-white"
style={{ animationDelay: "150ms" }}
/>
<span
className="h-3 w-3 animate-bounce rounded-full bg-white"
style={{ animationDelay: "300ms" }}
/>
</div>
<span className="sr-only">{label}</span>
</div>
);
}