diff --git a/src/app/components/carousel.tsx b/src/app/components/carousel.tsx
index 1052661..192c32b 100644
--- a/src/app/components/carousel.tsx
+++ b/src/app/components/carousel.tsx
@@ -28,7 +28,7 @@ export default function Carousel({ images, className }: Props) {
{images.map((src, index) => (
-
+
))}
diff --git a/src/app/components/image-viewer.tsx b/src/app/components/image-viewer.tsx
index 74aaeb1..b7f9e2d 100644
--- a/src/app/components/image-viewer.tsx
+++ b/src/app/components/image-viewer.tsx
@@ -1,8 +1,10 @@
"use client";
import Image from "next/image";
+
import { useEffect, useState } from "react";
import { createPortal } from "react-dom";
+import useEmblaCarousel from "embla-carousel-react";
import { Icon } from "@iconify/react";
interface Props {
@@ -11,12 +13,17 @@ interface Props {
width: number;
height: number;
className?: string;
+ images?: string[];
}
-export default function ImageViewer({ src, alt, width, height, className }: Props) {
+export default function ImageViewer({ src, alt, width, height, className, images = [] }: Props) {
const [isOpen, setIsOpen] = useState(false);
const [isVisible, setIsVisible] = useState(false);
+ const [emblaRef, emblaApi] = useEmblaCarousel();
+ const [selectedIndex, setSelectedIndex] = useState(0);
+ const [scrollSnaps, setScrollSnaps] = useState([]);
+
const close = () => {
setIsVisible(false);
setTimeout(() => {
@@ -31,6 +38,21 @@ export default function ImageViewer({ src, alt, width, height, className }: Prop
}
}, [isOpen]);
+ useEffect(() => {
+ if (!emblaApi) return;
+
+ // Keep order of images whilst opening on src
+ const index = images.indexOf(src);
+ if (index !== -1) {
+ emblaApi.scrollTo(index);
+ setSelectedIndex(index);
+ }
+
+ // Scroll snaps
+ setScrollSnaps(emblaApi.scrollSnapList());
+ emblaApi.on("select", () => setSelectedIndex(emblaApi.selectedScrollSnap()));
+ }, [emblaApi]);
+
return (
<>
setIsOpen(true)} />
@@ -50,13 +72,81 @@ export default function ImageViewer({ src, alt, width, height, className }: Prop
isVisible ? "scale-100 opacity-100" : "scale-75 opacity-0"
}`}
>
-
+
-
+
+
+
+ {images.length == 0 ? (
+
+ ) : (
+ <>
+ {images.map((image, index) => (
+
+
+
+ ))}
+ >
+ )}
+
+
+
+ {images.length != 0 && (
+ <>
+ {/* Carousel buttons */}
+ {/* Prev button */}
+
+
+
+ {/* Next button */}
+
+
+
+
+ {/* Carousel snaps */}
+
+ {scrollSnaps.map((_, index) => (
+
+ >
+ )}
,
document.body
)}