ifixkart-storefront/components/ui/BlurHashImage.tsx

61 lines
1.6 KiB
TypeScript

"use client";
import React, { useState, useEffect } from "react";
import Image, { ImageProps } from "next/image";
import { blurHashToDataURL } from "@/lib/blurhash";
export interface BlurHashImageProps extends Omit<ImageProps, "blurDataURL" | "placeholder"> {
blurHash?: string | null;
fallbackSrc?: string;
}
export function BlurHashImage({
src,
blurHash,
alt,
fallbackSrc = "/images/placeholder-product.webp",
className = "",
style,
...restProps
}: BlurHashImageProps) {
const [imgSrc, setImgSrc] = useState<string>(typeof src === "string" ? src : "");
const [blurDataUrl, setBlurDataUrl] = useState<string>(() => blurHashToDataURL(blurHash));
const [hasError, setHasError] = useState(false);
useEffect(() => {
if (typeof src === "string") {
setImgSrc(src);
setHasError(false);
}
}, [src]);
useEffect(() => {
setBlurDataUrl(blurHashToDataURL(blurHash));
}, [blurHash]);
const handleError = (e: React.SyntheticEvent<HTMLImageElement, Event>) => {
if (!hasError && fallbackSrc) {
setHasError(true);
setImgSrc(fallbackSrc);
}
if (restProps.onError) {
restProps.onError(e);
}
};
return (
<Image
{...restProps}
src={imgSrc || fallbackSrc}
alt={alt || "Product Image"}
placeholder={blurDataUrl && !hasError ? "blur" : undefined}
blurDataURL={blurDataUrl && !hasError ? blurDataUrl : undefined}
onError={handleError}
className={className}
style={style}
unoptimized={hasError || restProps.unoptimized || true}
/>
);
}
export default BlurHashImage;