Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- 'use client';
- import { useEffect } from 'react';
- import { CarouselArrow } from '@components/carousels/partials/Arrow';
- import { CarouselDot } from '@components/carousels/partials/Dot';
- import { ImageWithPreview } from '@components/ImageWithPreview';
- import { useCarousel } from '@hooks/useCarousel';
- import type { ImageWithAltAndCaption } from '@shared/types';
- import { clsxm } from '@utils';
- type Props = {
- images: ImageWithAltAndCaption[];
- options?: {
- animations?: boolean;
- preview?: {
- enabled?: boolean;
- type?: 'single' | 'multiple';
- };
- loop?: boolean;
- slidePosition?: number;
- };
- classNames?: {
- images?: {
- container?: string;
- image?: string;
- };
- };
- };
- export const ImageCarousel = ({ classNames, images, options }: Props) => {
- // Carousel Options
- const { animations = true, loop = false, preview, slidePosition } = options ?? {};
- const { enabled: hasPreview = true, type: previewType = 'single' } = preview ?? {};
- // Class Names
- const { container: imageContainerClassName = '', image: imageClassName = '' } =
- classNames?.images ?? {};
- // Instance Carousel
- const { currentSlide, instanceRef, loaded, sliderRef } = useCarousel({
- breakpoints: {
- '(max-width: 768px)': {
- slides: {
- spacing: 10,
- },
- },
- '(min-width: 769px)': {
- slides: {
- origin: 'center',
- perView: 2,
- spacing: 20,
- },
- },
- },
- initial: 0,
- loop,
- mode: 'free-snap',
- renderMode: 'performance',
- });
- const slidesLength = instanceRef?.current?.track.details?.slides?.length ?? images.length;
- useEffect(() => {
- if (slidePosition && loaded && instanceRef.current) {
- instanceRef.current?.moveToIdx(slidePosition);
- }
- }, [instanceRef, loaded, slidePosition]);
- return (
- <section className={clsxm([{ invisible: !loaded && !instanceRef.current }])}>
- <div
- className="keen-slider cursor-grab"
- data-aos={animations ? 'fade-left' : undefined}
- ref={sliderRef}
- >
- {images.map(image => (
- <ImageWithPreview
- key={image.asset?._ref}
- image={image}
- images={images}
- classNames={{
- container: clsxm(['keen-slider__slide', imageContainerClassName]),
- image: clsxm([
- 'bg-zinc-700 shadow-sm shadow-zinc-600/10 h-full max-h-[400px] w-full aspect-[none] md:aspect-video',
- imageClassName,
- ]),
- }}
- preview={{
- enabled: hasPreview,
- type: previewType,
- }}
- />
- ))}
- </div>
- {loaded && instanceRef.current && (
- <nav className="mt-2 flex items-center justify-between gap-4">
- <div className="flex items-center gap-4" data-aos={animations ? 'fade-right' : undefined}>
- <CarouselArrow
- left
- disabled={currentSlide === 0}
- onClick={(e: any) => e.stopPropagation() || instanceRef.current?.prev()}
- />
- <CarouselArrow
- disabled={currentSlide === slidesLength - 1}
- onClick={(e: any) => e.stopPropagation() || instanceRef.current?.next()}
- />
- </div>
- <div className="flex items-center gap-2" data-aos={animations ? 'fade-right' : undefined}>
- {[...Array(slidesLength).keys()].map(idx => (
- <CarouselDot
- key={idx}
- id={idx}
- isCurrentSlide={currentSlide === idx}
- variant="dark"
- onClick={() => {
- instanceRef.current?.moveToIdx(idx);
- }}
- />
- ))}
- </div>
- </nav>
- )}
- </section>
- );
- };
Advertisement
Add Comment
Please, Sign In to add comment