summaryrefslogtreecommitdiff
path: root/src/components/blur-image.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/blur-image.tsx')
-rw-r--r--src/components/blur-image.tsx43
1 files changed, 43 insertions, 0 deletions
diff --git a/src/components/blur-image.tsx b/src/components/blur-image.tsx
new file mode 100644
index 0000000..92dcc30
--- /dev/null
+++ b/src/components/blur-image.tsx
@@ -0,0 +1,43 @@
+'use client';
+/**
+ * Copyright (c) Delba de Oliveira
+ * Source: https://github.com/delbaoliveira/website/blob/59e6f181ad75751342ceaa8931db4cbcef86b018/ui/BlurImage.tsx
+ */
+import { cn } from '@/lib/utils';
+import NextImage from 'next/image';
+import { useState } from 'react';
+
+type ImageProps = {
+ imageClassName?: string;
+ lazy?: boolean;
+} & React.ComponentProps<typeof NextImage>;
+
+const BlurImage = (props: ImageProps) => {
+ const { alt, src, className, imageClassName, lazy = true, ...rest } = props;
+ const [isLoading, setIsLoading] = useState(true);
+
+ return (
+ <div
+ className={cn('overflow-hidden', isLoading && 'animate-pulse', className)}
+ >
+ <NextImage
+ className={cn(
+ isLoading && 'scale-[1.02] blur-xl grayscale',
+ imageClassName,
+ )}
+ style={{
+ transition: 'filter 700ms ease, scale 150ms ease',
+ }}
+ src={src}
+ alt={alt}
+ loading={lazy ? 'lazy' : undefined}
+ priority={!lazy}
+ quality={100}
+ onLoad={() => setIsLoading(false)}
+ {...rest}
+ />
+ </div>
+ );
+};
+
+export { BlurImage };