Feat(SW-337): Update lightbox UI * chore(SW-337): hotelPage UI fixes * refactor(SW-337): move width and height as props * xhore(SW-337): update lightbox UI * fix(SW-337): move margin * fix(SW-337): update mobile fullview * fix(SW-337): remove test border * fix(SW-337): remove radius on fullview Approved-by: Erik Tiekstra Approved-by: Fredrik Thorsson
173 lines
5.3 KiB
TypeScript
173 lines
5.3 KiB
TypeScript
"use client"
|
|
import { AnimatePresence, motion } from "framer-motion"
|
|
|
|
import { ChevronRightIcon } from "@/components/Icons"
|
|
import ArrowRightIcon from "@/components/Icons/ArrowRight"
|
|
import CloseIcon from "@/components/Icons/Close"
|
|
import Image from "@/components/Image"
|
|
import Button from "@/components/TempDesignSystem/Button"
|
|
import Caption from "@/components/TempDesignSystem/Text/Caption"
|
|
|
|
import styles from "./Lightbox.module.css"
|
|
|
|
import type { GalleryProps } from "@/types/components/lightbox/lightbox"
|
|
|
|
export default function Gallery({
|
|
images,
|
|
onClose,
|
|
onSelectImage,
|
|
onImageClick,
|
|
selectedImage,
|
|
}: GalleryProps) {
|
|
const mainImage = selectedImage || images[0]
|
|
const mainImageIndex = images.findIndex((img) => img === mainImage)
|
|
|
|
function getThumbImages() {
|
|
const thumbs = []
|
|
for (let i = 1; i <= 5; i++) {
|
|
const index = (mainImageIndex + i) % images.length
|
|
thumbs.push(images[index])
|
|
}
|
|
return thumbs
|
|
}
|
|
|
|
function handleNext() {
|
|
const nextIndex = (mainImageIndex + 1) % images.length
|
|
onSelectImage(images[nextIndex])
|
|
}
|
|
|
|
function handlePrev() {
|
|
const prevIndex = (mainImageIndex - 1 + images.length) % images.length
|
|
onSelectImage(images[prevIndex])
|
|
}
|
|
|
|
return (
|
|
<div className={styles.galleryContainer}>
|
|
<Button
|
|
intent="text"
|
|
size="small"
|
|
theme="base"
|
|
variant="icon"
|
|
className={styles.desktopGalleryCloseButton}
|
|
onClick={onClose}
|
|
>
|
|
<CloseIcon
|
|
width={32}
|
|
height={32}
|
|
className={styles.desktopGalleryCloseIcon}
|
|
/>
|
|
</Button>
|
|
{/* Desktop Gallery */}
|
|
<div className={styles.desktopGallery}>
|
|
<div className={styles.galleryHeader}>
|
|
{mainImage.metaData.title && (
|
|
<div className={styles.imageCaption}>
|
|
<Caption color="textMediumContrast">
|
|
{mainImage.metaData.title}
|
|
</Caption>
|
|
</div>
|
|
)}
|
|
</div>
|
|
<div className={styles.mainImageWrapper}>
|
|
<AnimatePresence initial={false} mode="wait">
|
|
<motion.div
|
|
key={mainImage.imageSizes.medium}
|
|
className={styles.mainImageContainer}
|
|
initial={{ opacity: 0, x: 300 }}
|
|
animate={{ opacity: 1, x: 0 }}
|
|
exit={{ opacity: 0, x: -300 }}
|
|
transition={{ duration: 0.3 }}
|
|
>
|
|
<Image
|
|
src={mainImage.imageSizes.medium}
|
|
alt={mainImage.metaData.altText}
|
|
fill
|
|
className={styles.image}
|
|
onClick={onImageClick}
|
|
/>
|
|
</motion.div>
|
|
</AnimatePresence>
|
|
<motion.button
|
|
className={`${styles.navigationButton} ${styles.galleryPrevButton}`}
|
|
onClick={handlePrev}
|
|
>
|
|
<ArrowRightIcon
|
|
color="burgundy"
|
|
className={styles.leftTransformIcon}
|
|
/>
|
|
</motion.button>
|
|
<motion.button
|
|
className={`${styles.navigationButton} ${styles.galleryNextButton}`}
|
|
onClick={handleNext}
|
|
>
|
|
<ArrowRightIcon color="burgundy" />
|
|
</motion.button>
|
|
</div>
|
|
<div className={styles.desktopThumbnailGrid}>
|
|
<AnimatePresence initial={false}>
|
|
{getThumbImages().map((image, index) => (
|
|
<motion.div
|
|
key={image.imageSizes.tiny}
|
|
className={styles.thumbnailContainer}
|
|
onClick={() => onSelectImage(image)}
|
|
initial={{ opacity: 0, x: 50 }}
|
|
animate={{ opacity: 1, x: 0 }}
|
|
exit={{ opacity: 0, x: -50 }}
|
|
transition={{ duration: 0.2, delay: index * 0.05 }}
|
|
>
|
|
<Image
|
|
src={image.imageSizes.tiny}
|
|
alt={image.metaData.altText}
|
|
fill
|
|
className={styles.image}
|
|
/>
|
|
</motion.div>
|
|
))}
|
|
</AnimatePresence>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Mobile Gallery */}
|
|
<div className={styles.mobileGallery}>
|
|
<Button
|
|
intent="text"
|
|
size="small"
|
|
className={styles.mobileGalleryCloseButton}
|
|
onClick={onClose}
|
|
>
|
|
<ChevronRightIcon
|
|
color="black"
|
|
width={32}
|
|
height={32}
|
|
className={styles.leftTransformIcon}
|
|
/>
|
|
</Button>
|
|
<div className={styles.mobileGalleryContent}>
|
|
<div className={styles.thumbnailGrid}>
|
|
{images.map((image, index) => (
|
|
<motion.div
|
|
key={image.imageSizes.small}
|
|
className={`${styles.thumbnailContainer} ${index % 3 === 0 ? styles.fullWidthImage : ""}`}
|
|
onClick={() => {
|
|
onSelectImage(image)
|
|
onImageClick()
|
|
}}
|
|
initial={{ opacity: 0, y: 20 }}
|
|
animate={{ opacity: 1, y: 0 }}
|
|
transition={{ duration: 0.3, delay: index * 0.05 }}
|
|
>
|
|
<Image
|
|
src={image.imageSizes.small}
|
|
alt={image.metaData.altText}
|
|
fill
|
|
className={styles.image}
|
|
/>
|
|
</motion.div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|