From 50536727a416fb23ff4a4e79bf419438c6191edb Mon Sep 17 00:00:00 2001 From: Sean O'Connor Date: Wed, 10 Dec 2025 03:20:46 -0500 Subject: [PATCH] feat: Add `ImageWithSkeleton` component and refactor `Sidebar` to use it. --- src/components/Sidebar.tsx | 49 +++++++++-------------- src/components/ui/image-with-skeleton.tsx | 37 +++++++++++++++++ 2 files changed, 56 insertions(+), 30 deletions(-) create mode 100644 src/components/ui/image-with-skeleton.tsx diff --git a/src/components/Sidebar.tsx b/src/components/Sidebar.tsx index 7c730d3..9095005 100644 --- a/src/components/Sidebar.tsx +++ b/src/components/Sidebar.tsx @@ -1,16 +1,13 @@ "use client"; -import Image from "next/image"; import { usePathname } from "next/navigation"; import { name, contact, location } from "~/lib/data"; -import { useState } from "react"; -import { Skeleton } from "~/components/ui/skeleton"; +import { ImageWithSkeleton } from "~/components/ui/image-with-skeleton"; export function Sidebar() { const pathname = usePathname(); const isHomePage = pathname === "/"; - const [isImageLoading, setIsImageLoading] = useState(true); return ( <> @@ -18,19 +15,15 @@ export function Sidebar() { {isHomePage && (
-
- {isImageLoading && } - {`${name[0]?.first} ${name[0]?.last}`} setIsImageLoading(false)} - priority - /> -
+

{name[0]?.first} {name[0]?.last} @@ -82,19 +75,15 @@ export function Sidebar() { {/* Profile Section */}
-
- {isImageLoading && } - {`${name[0]?.first} setIsImageLoading(false)} - priority - /> -
+

{name[0]?.first} {name[0]?.last} diff --git a/src/components/ui/image-with-skeleton.tsx b/src/components/ui/image-with-skeleton.tsx new file mode 100644 index 0000000..461a4a3 --- /dev/null +++ b/src/components/ui/image-with-skeleton.tsx @@ -0,0 +1,37 @@ +"use client"; + +import { useState } from "react"; +import Image, { ImageProps } from "next/image"; +import { Skeleton } from "~/components/ui/skeleton"; +import { cn } from "~/lib/utils"; + +interface ImageWithSkeletonProps extends ImageProps { + containerClassName?: string; +} + +export function ImageWithSkeleton({ + className, + containerClassName, + onLoad, + ...props +}: ImageWithSkeletonProps) { + const [isLoading, setIsLoading] = useState(true); + + return ( +
+ {isLoading && } + { + setIsLoading(false); + if (onLoad) onLoad(e); + }} + {...props} + /> +
+ ); +}