feat(components): add carousel components

it's inmidiatly used in the image gallery
This commit is contained in:
Alexander Navarro 2023-12-17 20:58:58 -03:00
parent 4f903c3c8d
commit 8f15b45e9b
6 changed files with 162 additions and 83 deletions

View file

@ -1,95 +1,29 @@
import React from 'react';
import { MediaType, type Media } from './types';
import { type Media } from './types';
import classes from './Gallery.module.css';
import LightGallery from 'lightgallery/react';
// import styles
import 'lightgallery/css/lightgallery.css';
import 'lightgallery/css/lg-zoom.css';
import 'lightgallery/css/lg-thumbnail.css';
// import plugins if you need
import lgThumbnail from 'lightgallery/plugins/thumbnail';
import lgZoom from 'lightgallery/plugins/zoom';
import lgVideo from 'lightgallery/plugins/video';
import Carousel from '@components/Carousel/Carousel';
import CarouselItem from '@components/Carousel/CarouselItem';
interface Props {
items: Media[];
height: number;
}
// TODO: Replace the external library for custom module
export default function Gallery({ items }: Props): JSX.Element {
const getUrlFromGoogleDrive = (
originalUrl: string,
type: MediaType,
): string => {
// get the file id from the "share" link of google drive
const googleFileId = originalUrl.split('/').at(5);
if (googleFileId == null) {
return originalUrl;
}
switch (type) {
case MediaType.Image:
return `https://drive.google.com/uc?export=preview&id=${googleFileId}`;
case MediaType.Video:
return `https://drive.google.com/file/d/${googleFileId}/preview`;
default:
return '';
}
};
const renderItem = (item: Media, index: number): JSX.Element => {
// get the file id from the "share" link of google drive
const url = getUrlFromGoogleDrive(item.url, item.type);
let thumbnail;
if (item.thumbnail !== undefined) {
thumbnail = getUrlFromGoogleDrive(item.thumbnail, MediaType.Image);
} else {
thumbnail = url;
}
switch (item.type) {
case MediaType.Image:
return (
<a key={index} href={url} className={classes.thumbnailItem}>
<img src={url} alt={item.alt} />
</a>
);
case MediaType.Video:
return (
<div
key={index}
className={classes.thumbnailItem}
data-src={url}
data-iframe={true}
id={item.url}
data-iframe-title="foo"
>
<img src={thumbnail} alt={item.alt} />
</div>
);
default:
break;
}
return <></>;
};
export default function Gallery({ items, height = 500 }: Props): JSX.Element {
return (
<div>
<LightGallery
speed={500}
plugins={[lgThumbnail, lgZoom, lgVideo]}
elementClassNames={classes.thumbnailList}
>
{items.map(renderItem)}
</LightGallery>
<div style={{ height }}>
<Carousel>
{items.map((item, idx) => (
<CarouselItem key={idx}>
<img
className="respect-height"
src={item.thumbnail ?? item.url}
alt={item.alt}
/>
</CarouselItem>
))}
</Carousel>
</div>
);
}