From 1a2139b6fc7354c87439e43f00bc3492ce898a35 Mon Sep 17 00:00:00 2001 From: John Doe Date: Sun, 10 Sep 2023 17:53:55 +0300 Subject: [PATCH] =?UTF-8?q?=F0=9F=9B=A0=EF=B8=8F=20Fixed=20a=20bug=20in=20?= =?UTF-8?q?GallerySlider=20component=20=F0=9F=9A=A7=20Work=20in=20progress?= =?UTF-8?q?=20on=20GallerySlider=20=F0=9F=93=B8=20Added=20new=20images=20t?= =?UTF-8?q?o=20the=20gallery=20=E2=9C=A8=20Implemented=20swipe=20functiona?= =?UTF-8?q?lity=20=F0=9F=8E=A8=20Improved=20styling=20in=20GallerySlider?= =?UTF-8?q?=20component?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/GallerySlider.tsx | 146 +++++++++++++++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100644 src/components/GallerySlider.tsx diff --git a/src/components/GallerySlider.tsx b/src/components/GallerySlider.tsx new file mode 100644 index 0000000..865a718 --- /dev/null +++ b/src/components/GallerySlider.tsx @@ -0,0 +1,146 @@ +"use client"; + +import { ChevronLeftIcon, ChevronRightIcon } from "@heroicons/react/24/outline"; +import { AnimatePresence, motion, MotionConfig } from "framer-motion"; +import Image, { StaticImageData } from "next/image"; +import { useState } from "react"; +import { useSwipeable } from "react-swipeable"; +import { variants } from "@/utils/animationVariants"; +import Link from "next/link"; +import { Route } from "@/routers/types"; + +export interface GallerySliderProps { + className?: string; + galleryImgs: (StaticImageData | string)[]; + ratioClass?: string; + uniqueID: string; + href?: Route; + imageClass?: string; + galleryClass?: string; + navigation?: boolean; +} + +export default function GallerySlider({ + className = "", + galleryImgs, + ratioClass = "aspect-w-4 aspect-h-3", + imageClass = "", + uniqueID = "uniqueID", + galleryClass = "rounded-xl", + href = "/listing-stay-detail", + navigation = true, +}: GallerySliderProps) { + const [loaded, setLoaded] = useState(false); + const [index, setIndex] = useState(0); + const [direction, setDirection] = useState(0); + const images = galleryImgs; + + function changePhotoId(newVal: number) { + if (newVal > index) { + setDirection(1); + } else { + setDirection(-1); + } + setIndex(newVal); + } + + const handlers = useSwipeable({ + onSwipedLeft: () => { + if (index < images?.length - 1) { + changePhotoId(index + 1); + } + }, + onSwipedRight: () => { + if (index > 0) { + changePhotoId(index - 1); + } + }, + trackMouse: true, + }); + + let currentImage = images[index]; + + return ( + +
+ {/* Main image */} +
+ + + + listing card gallery setLoaded(true)} + sizes="(max-width: 1025px) 100vw, 300px" + /> + + + +
+ + {/* Buttons + bottom nav bar */} + <> + {/* Buttons */} + {loaded && navigation && ( +
+ {index > 0 && ( + + )} + {index + 1 < images.length && ( + + )} +
+ )} + + {/* Bottom Nav bar */} +
+
+ {images.map((_, i) => ( +
+ +
+
+ ); +}