From 5b7ccf0b671e2999b62befc729a3e517a0433728 Mon Sep 17 00:00:00 2001
From: Bertrand Yuan <bert.yuan@outlook.com>
Date: Mon, 15 Dec 2025 23:48:10 +0800
Subject: initial commit -- the front-end prototype

The initial code is base on Anirudh's work.

More to see at:

    https://github.com/techwithanirudh/shadcn-blog

Therefore, the code in this commit is under MIT license.
---
 src/components/blur-image.tsx | 43 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 43 insertions(+)
 create mode 100644 src/components/blur-image.tsx

(limited to 'src/components/blur-image.tsx')

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 };
-- 
cgit v1.2.3

