From 5543d96df9be79267576c507316dc561e48054fb Mon Sep 17 00:00:00 2001 From: AbhinRustagi Date: Tue, 23 Jun 2026 14:45:48 +0530 Subject: [PATCH] feat: add skeleton loader component Add a lightweight shimmering placeholder primitive for line, pill, and avatar loading states. Co-authored-by: Cursor --- components/motion/skeleton-loader.tsx | 40 +++++++++++++++++++ components/previews/index.tsx | 3 ++ .../motion/skeleton-loader.preview.tsx | 28 +++++++++++++ lib/registry.ts | 7 ++++ 4 files changed, 78 insertions(+) create mode 100644 components/motion/skeleton-loader.tsx create mode 100644 components/previews/motion/skeleton-loader.preview.tsx diff --git a/components/motion/skeleton-loader.tsx b/components/motion/skeleton-loader.tsx new file mode 100644 index 0000000..750d2f5 --- /dev/null +++ b/components/motion/skeleton-loader.tsx @@ -0,0 +1,40 @@ +import { cn } from "@/lib/utils"; + +export interface SkeletonLoaderProps { + className?: string; + width?: number | string; + height?: number | string; + circle?: boolean; + shimmer?: boolean; +} + +export function SkeletonLoader({ + className, + width, + height = 16, + circle = false, + shimmer = true, +}: SkeletonLoaderProps) { + return ( + <> + + + + ); +} diff --git a/components/previews/index.tsx b/components/previews/index.tsx index 88b30f4..6fc5b89 100644 --- a/components/previews/index.tsx +++ b/components/previews/index.tsx @@ -140,6 +140,9 @@ export const previews: Record = { "motion/theme-toggle": dynamic(() => import("./motion/theme-toggle.preview").then((m) => m.ThemeTogglePreview), ), + "motion/skeleton-loader": dynamic(() => + import("./motion/skeleton-loader.preview").then((m) => m.SkeletonLoaderPreview), + ), }; export function getPreview(category: string, slug: string) { diff --git a/components/previews/motion/skeleton-loader.preview.tsx b/components/previews/motion/skeleton-loader.preview.tsx new file mode 100644 index 0000000..134f45e --- /dev/null +++ b/components/previews/motion/skeleton-loader.preview.tsx @@ -0,0 +1,28 @@ +"use client"; + +import { SkeletonLoader } from "@/components/motion/skeleton-loader"; + +export function SkeletonLoaderPreview() { + return ( +
+
+ +
+ + +
+
+ +
+ + + +
+ +
+ + +
+
+ ); +} diff --git a/lib/registry.ts b/lib/registry.ts index cec5ace..694701b 100644 --- a/lib/registry.ts +++ b/lib/registry.ts @@ -252,6 +252,13 @@ export const registry: CategoryEntry[] = [ description: "Theme toggle button with a full-page rectangle clip-path reveal via the View Transition API.", file: "components/motion/theme-toggle.tsx", }, + { + slug: "skeleton-loader", + name: "Skeleton Loader", + description: "Shimmering placeholder block for loading states, with line, pill and circular avatar shapes.", + file: "components/motion/skeleton-loader.tsx", + badge: "new", + }, { slug: "bouncy-accordion", name: "Bouncy Accordion",