|
1 | | -import { Box, Grid, GridItem } from "@chakra-ui/react"; |
2 | | -import { FC } from "react"; |
| 1 | +import { Grid, GridItem } from "@chakra-ui/react"; |
| 2 | +import { DetailedHTMLProps, FC, HTMLAttributes } from "react"; |
| 3 | +import { twMerge } from "tailwind-merge"; |
3 | 4 |
|
4 | 5 | import GalleryImage from "../../Images/GalleryImage/GalleryImage"; |
5 | | -import { MIN_ITEMS } from "./constants"; |
| 6 | +import { MIN_ITEMS, MIN_ROWS } from "./constants"; |
6 | 7 |
|
7 | | -interface IImageGalleryCardProps { |
8 | | - images: string[] | undefined; |
| 8 | +export interface GalleryImageType { |
| 9 | + uuid: string; |
| 10 | + src: string; |
| 11 | + alt: string; |
| 12 | +} |
| 13 | + |
| 14 | +interface IImageGalleryCardProps extends DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement> { |
| 15 | + images: GalleryImageType[]; |
9 | 16 | onClickAdd?: () => void; |
| 17 | + columns?: number; |
| 18 | + imageSize?: number; |
| 19 | + className?: string; |
| 20 | + onSelectImage?: (image: GalleryImageType) => void; |
10 | 21 | } |
11 | 22 |
|
12 | | -const ImageGalleryCard: FC<IImageGalleryCardProps> = ({ images, onClickAdd }) => { |
| 23 | +const ImageGalleryCard: FC<IImageGalleryCardProps> = ({ |
| 24 | + images, |
| 25 | + onClickAdd, |
| 26 | + columns = 2, |
| 27 | + imageSize = 164, |
| 28 | + onSelectImage, |
| 29 | + onScroll, |
| 30 | + className |
| 31 | +}) => { |
13 | 32 | const imageCount = images?.length ?? 0; |
14 | | - const itemsToShow = Math.max(MIN_ITEMS, imageCount); |
| 33 | + const minimumCapacity = Math.max(MIN_ITEMS, columns * MIN_ROWS); |
| 34 | + const roundedCapacity = Math.ceil(Math.max(imageCount, 1) / columns) * columns; |
| 35 | + const itemsToShow = Math.max(minimumCapacity, roundedCapacity); |
15 | 36 | const placeholderCount = itemsToShow - imageCount; |
16 | 37 | const isEmpty = imageCount === 0; |
17 | 38 |
|
18 | 39 | return ( |
19 | | - <Box padding={5} backgroundColor="white" borderRadius="md"> |
20 | | - <Grid templateColumns="repeat(2, 1fr)" gapY={5} gapX={5}> |
21 | | - {images?.map((image, index) => ( |
22 | | - <GridItem key={`image-${index}-${image}`}> |
23 | | - <GalleryImage |
24 | | - src={image} |
25 | | - alt="Image" |
26 | | - className="bg-theme-neutral-200 h-full min-h-full w-full min-w-full" |
27 | | - /> |
28 | | - </GridItem> |
29 | | - ))} |
30 | | - {Array.from({ length: placeholderCount }).map((_, index) => { |
31 | | - const isFirstPlaceholder = index === 0; |
32 | | - const showContent = isEmpty && isFirstPlaceholder; |
| 40 | + <Grid |
| 41 | + templateColumns={`repeat(${columns}, 1fr)`} |
| 42 | + gapY={5} |
| 43 | + gapX={5} |
| 44 | + onScroll={onScroll} |
| 45 | + className={twMerge("bg-theme-neutral-100 rounded-md p-5", className)} |
| 46 | + > |
| 47 | + {images?.map(image => ( |
| 48 | + <GridItem key={image.uuid}> |
| 49 | + <GalleryImage |
| 50 | + onClickEdit={onSelectImage && (() => onSelectImage(image))} |
| 51 | + src={image.src} |
| 52 | + alt={image.alt} |
| 53 | + size={imageSize} |
| 54 | + className="bg-theme-neutral-200 min-w-full" |
| 55 | + hoverContent={" "} |
| 56 | + /> |
| 57 | + </GridItem> |
| 58 | + ))} |
| 59 | + {Array.from({ length: placeholderCount }).map((_, index) => { |
| 60 | + const isFirstPlaceholder = index === 0; |
| 61 | + const showContent = isEmpty && isFirstPlaceholder; |
33 | 62 |
|
34 | | - return ( |
35 | | - <GridItem key={`placeholder-${index}`}> |
36 | | - {showContent ? ( |
37 | | - <GalleryImage alt="No images available" isAdd={true} onClickEdit={onClickAdd} /> |
38 | | - ) : ( |
39 | | - <div className="bg-theme-neutral-200 rounded-md" style={{ width: 164, height: 164 }} /> |
40 | | - )} |
41 | | - </GridItem> |
42 | | - ); |
43 | | - })} |
44 | | - </Grid> |
45 | | - </Box> |
| 63 | + return ( |
| 64 | + <GridItem key={`placeholder-${index}`}> |
| 65 | + {showContent ? ( |
| 66 | + <GalleryImage |
| 67 | + className="min-w-full" |
| 68 | + alt="No images available" |
| 69 | + isAdd={true} |
| 70 | + onClickAdd={onClickAdd} |
| 71 | + size={imageSize} |
| 72 | + /> |
| 73 | + ) : ( |
| 74 | + <div |
| 75 | + className="bg-theme-neutral-200 min-w-full rounded-md" |
| 76 | + style={{ width: imageSize, height: imageSize }} |
| 77 | + /> |
| 78 | + )} |
| 79 | + </GridItem> |
| 80 | + ); |
| 81 | + })} |
| 82 | + </Grid> |
46 | 83 | ); |
47 | 84 | }; |
48 | 85 |
|
|
0 commit comments