Dot Loader
paceui-gsap/dot-loaderFreeComponent
A compact 7x7 dot grid loader with smooth animation to visualize frame sequences or loading states in your app.
Live preview
live · rendered by the registry
Rendered by PaceUI GSAP on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://gsap.paceui.com/r/dot-loader.jsonSource
1"use client";23import { ComponentProps, useCallback, useEffect, useRef } from "react";45import { cn } from "@/lib/utils";67type DotLoaderProps = {8 frames: number[][];9 dotClassName?: string;10 isPlaying?: boolean;11 duration?: number;12 repeatCount?: number;13 onComplete?: () => void;14} & ComponentProps<"div">;1516export const DotLoader = ({17 frames,18 isPlaying = true,19 duration = 100,20 dotClassName,21 className,22 repeatCount = -1,23 onComplete,24 ...props25}: DotLoaderProps) => {26 const gridRef = useRef<HTMLDivElement>(null);27 const currentIndex = useRef(0);28 const repeats = useRef(0);29 const interval = useRef<NodeJS.Timeout>(null);3031 const applyFrameToDots = useCallback(32 (dots: HTMLDivElement[], frameIndex: number) => {33 const frame = frames[frameIndex];34 if (!frame) return;3536 dots.forEach((dot, index) => {37 dot.classList.toggle("active", frame.includes(index));38 });39 },40 [frames],41 );4243 useEffect(() => {44 currentIndex.current = 0;45 repeats.current = 0;46 }, [frames]);4748 useEffect(() => {49 if (isPlaying) {50 if (currentIndex.current >= frames.length) {51 currentIndex.current = 0;52 }53 const dotElements = gridRef.current?.children;54 if (!dotElements) return;55 const dots = Array.from(dotElements) as HTMLDivElement[];56 interval.current = setInterval(() => {57 applyFrameToDots(dots, currentIndex.current);58 if (currentIndex.current + 1 >= frames.length) {59 if (repeatCount != -1 && repeats.current + 1 >= repeatCount) {60 clearInterval(interval.current!);61 onComplete?.();62 }63 repeats.current++;64 }65 currentIndex.current = (currentIndex.current + 1) % frames.length;66 }, duration);67 } else {68 if (interval.current) clearInterval(interval.current);69 }7071 return () => {72 if (interval.current) clearInterval(interval.current);73 };74 }, [frames, isPlaying, applyFrameToDots, duration, repeatCount, onComplete]);7576 return (77 <div {...props} ref={gridRef} className={cn("grid w-fit grid-cols-7 gap-0.5", className)}>78 {Array.from({ length: 49 }).map((_, i) => (79// … truncated
Files it writes
More from PaceUI GSAP
All 29 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Modal Ability Selectorai-modal-ability-selector | PaceUI GSAP | Components | Free | 2 deps | |
| Modal Selectorai-modal-selector | PaceUI GSAP | Components | Free | 2 deps | |
| Response Writerai-response-writer | PaceUI GSAP | Components | Free | 2 deps · 2 files | |
| AI Suggestionsai-suggestions | PaceUI GSAP | Components | Free | 2 deps | |
| Modal Ability Selectorai-token-counter | PaceUI GSAP | Components | Free | 2 deps | |
| Animated Stackanimated-stack | PaceUI GSAP | Components | Free | 2 deps | |
| Bouncing Textbouncing-text | PaceUI GSAP | Components | Free | 2 deps | |
| Dot Flowdot-flow | PaceUI GSAP | Components | Free | 2 deps |
