* fix(SW-1563): Added new IconButton component to the design system and removed Icon variant inside the Button component * fix(SW-1563): Added buttons around clickable images and changed to design system components * fix(SW-1563): Renamed variants to match Figma * fix(SW-1563): Renamed AriaButton to ButtonRAC Approved-by: Michael Zetterberg Approved-by: Matilda Landström
101 lines
2.8 KiB
TypeScript
101 lines
2.8 KiB
TypeScript
"use client"
|
|
import { AnimatePresence, motion } from "framer-motion"
|
|
import { useEffect, useState } from "react"
|
|
import { Dialog, Modal, ModalOverlay } from "react-aria-components"
|
|
|
|
import FullView from "./FullView"
|
|
import Gallery from "./Gallery"
|
|
|
|
import styles from "./lightbox.module.css"
|
|
|
|
import type { LightboxProps } from "@/types/components/lightbox/lightbox"
|
|
|
|
export default function Lightbox({
|
|
images,
|
|
dialogTitle,
|
|
onClose,
|
|
isOpen,
|
|
activeIndex = 0,
|
|
hideLabel,
|
|
}: LightboxProps) {
|
|
const [selectedImageIndex, setSelectedImageIndex] = useState(activeIndex)
|
|
const [isFullView, setIsFullView] = useState(false)
|
|
|
|
useEffect(() => {
|
|
if (isOpen) {
|
|
setIsFullView(false)
|
|
}
|
|
}, [isOpen])
|
|
|
|
useEffect(() => {
|
|
setSelectedImageIndex(activeIndex)
|
|
}, [activeIndex])
|
|
|
|
function handleClose() {
|
|
setSelectedImageIndex(0)
|
|
onClose()
|
|
}
|
|
|
|
function handleNext() {
|
|
setSelectedImageIndex((prevIndex) => (prevIndex + 1) % images.length)
|
|
}
|
|
|
|
function handlePrev() {
|
|
setSelectedImageIndex(
|
|
(prevIndex) => (prevIndex - 1 + images.length) % images.length
|
|
)
|
|
}
|
|
|
|
return (
|
|
<ModalOverlay
|
|
isOpen={isOpen}
|
|
onOpenChange={handleClose}
|
|
className={styles.overlay}
|
|
isDismissable
|
|
>
|
|
<Modal>
|
|
<AnimatePresence>
|
|
<Dialog aria-label={dialogTitle}>
|
|
{isOpen && (
|
|
<motion.div
|
|
className={`${styles.content} ${
|
|
isFullView ? styles.fullViewContent : styles.galleryContent
|
|
}`}
|
|
initial={{ opacity: 0, scale: 0.95 }}
|
|
animate={{ opacity: 1, scale: 1, x: "-50%", y: "-50%" }}
|
|
exit={{ opacity: 0, scale: 0.95 }}
|
|
transition={{ duration: 0.2 }}
|
|
>
|
|
{isFullView ? (
|
|
<FullView
|
|
image={images[selectedImageIndex]}
|
|
onClose={() => setIsFullView(false)}
|
|
onNext={handleNext}
|
|
onPrev={handlePrev}
|
|
currentIndex={selectedImageIndex}
|
|
totalImages={images.length}
|
|
hideLabel={hideLabel}
|
|
/>
|
|
) : (
|
|
<Gallery
|
|
images={images}
|
|
onClose={onClose}
|
|
onSelectImage={(image) => {
|
|
setSelectedImageIndex(
|
|
images.findIndex((img) => img === image)
|
|
)
|
|
}}
|
|
onImageClick={() => setIsFullView(true)}
|
|
selectedImage={images[selectedImageIndex]}
|
|
hideLabel={hideLabel}
|
|
/>
|
|
)}
|
|
</motion.div>
|
|
)}
|
|
</Dialog>
|
|
</AnimatePresence>
|
|
</Modal>
|
|
</ModalOverlay>
|
|
)
|
|
}
|