Skip to content

Commit

Permalink
ember carousel, replace old one
Browse files Browse the repository at this point in the history
  • Loading branch information
GraemeFulton committed Feb 10, 2024
1 parent 8c14648 commit 783ec45
Show file tree
Hide file tree
Showing 22 changed files with 1,690 additions and 119 deletions.
49 changes: 49 additions & 0 deletions components/carousel/Carousel.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import React, { useEffect } from 'react'
import useEmblaCarousel from 'embla-carousel-react'
import gumletLoader from "@/components/new-index/gumletLoader";
import Image from "next/image";

const Carousel = ({gallery})=> {
const [emblaRef, emblaApi] = useEmblaCarousel({ loop: false })

useEffect(() => {
if (emblaApi) {
console.log(emblaApi.slideNodes()) // Access API
}
}, [emblaApi])

return (
<div className="embla -ml-[24px] overflow-hidden" ref={emblaRef}>
<div className="embla__container ">
{gallery?.map((current, index) => (
<div className="embla__slide rounded-xl mb-4 ">
<div className="relative w-full rounded-xl h-60 sm:h-96 w-full lg:max-h-full relative overflow-hidden rounded-lg flex justify-center">
<Image
loader={gumletLoader}
layout="fill"
objectFit="cover"
priority={index == 0 ? true : false}
fetchpriority={index == 0 ? "true" : "false"}
data-priority={index == 0 ? `true` : `false`}
data-gmlazy={index == 0 ? `false` : `true`}
// className="rounded-lg object-contain h-60 sm:h-96"
src={current.original}
// data-src={current.original}
alt={`Gallery Image ${index}`}
sizes={"(max-width: 300px) 100vw, 600px"}
className='shadow-md rounded-xl'
/>
</div>
</div>
))}


{/* <div className="embla__slide">Slide 1</div>
<div className="embla__slide">Slide 2</div>
<div className="embla__slide">Slide 3</div> */}
</div>
</div>
)
}

export default Carousel
110 changes: 110 additions & 0 deletions components/carousel/EmblaCarousel.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import React, { useState, useEffect, useCallback } from 'react'
import useEmblaCarousel from 'embla-carousel-react'
import { Thumb } from './EmblaCarouselThumbsButton'
// import imageByIndex from './imageByIndex'
import Image from "next/image";
import gumletLoader from "@/components/new-index/gumletLoader";

import {
PrevButton,
NextButton,
usePrevNextButtons
} from './EmblaCarouselArrowButtons'

const EmblaCarousel = (props) => {
const { slides, options } = props
const [selectedIndex, setSelectedIndex] = useState(0)
const [emblaMainRef, emblaMainApi] = useEmblaCarousel(options)
const [emblaThumbsRef, emblaThumbsApi] = useEmblaCarousel({
containScroll: 'keepSnaps',
dragFree: true
})

const onThumbClick = useCallback(
(index) => {
if (!emblaMainApi || !emblaThumbsApi) return
emblaMainApi.scrollTo(index)
},
[emblaMainApi, emblaThumbsApi]
)

const onSelect = useCallback(() => {
if (!emblaMainApi || !emblaThumbsApi) return
setSelectedIndex(emblaMainApi.selectedScrollSnap())
emblaThumbsApi.scrollTo(emblaMainApi.selectedScrollSnap())
}, [emblaMainApi, emblaThumbsApi, setSelectedIndex])

useEffect(() => {
if (!emblaMainApi) return
onSelect()
emblaMainApi.on('select', onSelect)
emblaMainApi.on('reInit', onSelect)
}, [emblaMainApi, onSelect])

const {
prevBtnDisabled,
nextBtnDisabled,
onPrevButtonClick,
onNextButtonClick
} = usePrevNextButtons(emblaMainApi)

return (
<div className="embla px-14 py-6 -ml-[1.6rem] -mt-[1.6rem] relative">
<div className="embla__buttons absolute top-0 w-full flex justify-between -mt-[2rem]">
<PrevButton onClick={onPrevButtonClick} disabled={prevBtnDisabled} />
<NextButton onClick={onNextButtonClick} disabled={nextBtnDisabled} />
</div>
<div className="embla__viewport" ref={emblaMainRef}>
<div className="embla__container">
{slides.map((item,index) => (
<div className="embla__slide pb-4" key={index}>
<div className="embla__slide__number">
<span>{index + 1}</span>
</div>
{/* <img
className="embla__slide__img"
src={item.original}
alt="Your alt text"
/> */}
<div className="relative shadow-md w-full rounded-xl h-[200px] sm:h-[300px] w-full lg:max-h-full relative overflow-hidden flex justify-center">
<Image
loader={gumletLoader}
layout="fill"
objectFit="cover"
priority={index == 0 ? true : false}
fetchpriority={index == 0 ? "true" : "false"}
data-priority={index == 0 ? `true` : `false`}
data-gmlazy={index == 0 ? `false` : `true`}
// className="rounded-lg object-contain h-60 sm:h-96"
src={item.original}
// data-src={current.original}
alt={`Gallery Image ${index}`}
sizes={"(max-width: 300px) 100vw, 600px"}
className='embla__slide__img rounded-xl shadow-xl p-[4px] bg-white border border-gray-200'
/>
</div>
</div>
))}
</div>
</div>

<div className="embla-thumbs w-fit max-w-full mx-auto">
<div className="embla-thumbs__viewport p-1 -mt-2" ref={emblaThumbsRef}>
<div className="embla-thumbs__container">
{slides.map((item,index) => (
<Thumb
onClick={() => onThumbClick(index)}
selected={index === selectedIndex}
index={index}
imgSrc={item.thumbnail}
key={index}
/>
))}
</div>
</div>
</div>
</div>
)
}

export default EmblaCarousel
87 changes: 87 additions & 0 deletions components/carousel/EmblaCarouselArrowButtons.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import React, { useCallback, useEffect, useState } from 'react'

export const usePrevNextButtons = (emblaApi) => {
const [prevBtnDisabled, setPrevBtnDisabled] = useState(true)
const [nextBtnDisabled, setNextBtnDisabled] = useState(true)

const onPrevButtonClick = useCallback(() => {
if (!emblaApi) return
emblaApi.scrollPrev()
}, [emblaApi])

const onNextButtonClick = useCallback(() => {
if (!emblaApi) return
emblaApi.scrollNext()
}, [emblaApi])

const onSelect = useCallback((emblaApi) => {
setPrevBtnDisabled(!emblaApi.canScrollPrev())
setNextBtnDisabled(!emblaApi.canScrollNext())
}, [])

useEffect(() => {
if (!emblaApi) return

onSelect(emblaApi)
emblaApi.on('reInit', onSelect)
emblaApi.on('select', onSelect)
}, [emblaApi, onSelect])

return {
prevBtnDisabled,
nextBtnDisabled,
onPrevButtonClick,
onNextButtonClick
}
}

export const PrevButton = (props) => {
const { children, ...restProps } = props

return (
<button
className="embla__button w-8 h-8 embla__button--prev rounded-full bg-white shadow border border-1 border-gray-300"
type="button"
{...restProps}
>
<svg
className="embla__button__svg"
xmlns="http://www.w3.org/2000/svg"
width="32"
height="32"
viewBox="0 0 256 256"
>
<path d="M224 128a8 8 0 01-8 8H59.31l58.35 58.34a8 8 0 01-11.32 11.32l-72-72a8 8 0 010-11.32l72-72a8 8 0 0111.32 11.32L59.31 120H216a8 8 0 018 8z"></path>
</svg> {/* <svg className="embla__button__svg" viewBox="0 0 532 532">
<path
fill="currentColor"
d="M355.66 11.354c13.793-13.805 36.208-13.805 50.001 0 13.785 13.804 13.785 36.238 0 50.034L201.22 266l204.442 204.61c13.785 13.805 13.785 36.239 0 50.044-13.793 13.796-36.208 13.796-50.002 0a5994246.277 5994246.277 0 0 0-229.332-229.454 35.065 35.065 0 0 1-10.326-25.126c0-9.2 3.393-18.26 10.326-25.2C172.192 194.973 332.731 34.31 355.66 11.354Z"
/>
</svg> */}
{children}
</button>
)
}

export const NextButton = (props) => {
const { children, ...restProps } = props

return (
<button
className="embla__button w-8 h-8 embla__button--next rounded-full bg-white shadow border border-1 border-gray-300"
type="button"
{...restProps}
>
<svg
className="embla__button__svg"
xmlns="http://www.w3.org/2000/svg"
width="32"
height="32"
viewBox="0 0 256 256"
>
<path d="M221.66 133.66l-72 72a8 8 0 01-11.32-11.32L196.69 136H40a8 8 0 010-16h156.69l-58.35-58.34a8 8 0 0111.32-11.32l72 72a8 8 0 010 11.32z"></path>
</svg>
{children}
</button>
)
}
57 changes: 57 additions & 0 deletions components/carousel/EmblaCarouselThumbsButton.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import React from 'react'
import Image from "next/image";
import gumletLoader from "@/components/new-index/gumletLoader";

export const Thumb = (props) => {
const { selected, imgSrc, index, onClick } = props

return (
<div
className={'embla-thumbs__slide'.concat(
selected ? ' embla-thumbs__slide--selected' : ''
)}
>
<button
onClick={onClick}
className="embla-thumbs__slide__button"
type="button"
>
<div className="embla-thumbs__slide__number">
<span>{index + 1}</span>
</div>
{/* <div className="rounded bg-white w-[64px] h-[48px] h-full mr-[15px]">
<Image
priority={index == 0 ? `true` : `false`}
fetchpriority={index == 0 ? "true" : "false"}
data-priority={index == 0 ? `true` : `false`}
data-gmlazy={index == 0 ? `false` : `true`}
loader={gumletLoader}
layout="fill"
className={`rounded-xl outline ${selected?'outline-[3px] outline-blue-500 shadow-lg':'outline-[1px] outline-gray-200'}`}
src={imgSrc}
alt={`Gallery Image ${index+1}`}
/>
</div> */}
<div className={`embla-thumbs__slide__img overflow-hdden relative rounded-lg outline ${selected?'outline-[3px] outline-blue-500 shadow-lg':'outline-[1px] outline-gray-200'}`}>
<Image
className="shine w-full h-full cursor-pointer bg-white object-cover rounded-lg"
src={imgSrc}
alt={`Gallery Image ${index+1}`}
loader={gumletLoader}
layout="fill"
priority={index == 0 ? `true` : `false`}
fetchpriority={index == 0 ? "true" : "false"}
data-priority={index == 0 ? `true` : `false`}
data-gmlazy={index == 0 ? `false` : `true`}
/>
</div>

{/* <img
className={`embla-thumbs__slide__img rounded-xl outline ${selected?'outline-[3px] outline-blue-500 shadow-lg':'outline-[1px] outline-gray-200'}`}
src={imgSrc}
alt="Your alt text"
/> */}
</button>
</div>
)
}
21 changes: 21 additions & 0 deletions components/carousel/Footer.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React from 'react'

const Footer = () => (
<footer className="sandbox__footer">
<a
className="sandbox__footer__link"
href="https://github.com/davidjerleke/embla-carousel"
>
<svg
className="sandbox__footer__link__svg"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
>
<path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z" />
</svg>
<span className="sandbox__footer__link__text">Visit on GitHub</span>
</a>
</footer>
)

export default Footer
9 changes: 9 additions & 0 deletions components/carousel/Header.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import React from 'react'

const Header = () => (
<header>
<h1 className="sandbox__header">Embla Carousel Thumbs React</h1>
</header>
)

export default Header
10 changes: 10 additions & 0 deletions components/carousel/imageByIndex.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import image1 from '../images/slide-1.jpg'
import image2 from '../images/slide-2.jpg'
import image3 from '../images/slide-3.jpg'
import image4 from '../images/slide-4.jpg'

export const images = [image1, image2, image3, image4]

const imageByIndex = (index) => images[index % images.length]

export default imageByIndex
21 changes: 21 additions & 0 deletions components/carousel/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React from 'react'
import ReactDOM from 'react-dom/client'
import EmblaCarousel from './EmblaCarousel'
import Header from './Header'
import Footer from './Footer'
// import '../css/base.css'
// import '../css/sandbox.css'
// import '../css/embla.css'

const OPTIONS = { align: 'start' }
const SLIDE_COUNT = 10
const SLIDES = Array.from(Array(SLIDE_COUNT).keys())

const Carousel = ({gallery}) => (
<section className="sandbox__carousel">
<EmblaCarousel slides={gallery} options={OPTIONS} />
</section>
)


export default Carousel
4 changes: 2 additions & 2 deletions components/v4/card/CategoriesIconCard.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const CategoriesIconCard = ({ topic, withBackground, showCount }) => {
});
}}
className="flex"
><div className={`${withBackground?'bg-white rounded-xl p-4':''} bg-gray-100 w-full h-auto rounded-xl cursor-pointer flex flex-col`}>
><div className={`${withBackground?'bg-white rounded-xl p-4':''} shadow-sm w-full h-auto rounded-xl cursor-pointer flex flex-col`}>
<div className="flex flex-row justify-between rounded-xl">
<div className="flex flex-col pl-1 justify-center">
<div className="capitalize overflow-hidden line-clamp-1 inline font-medium py-0 mb-0.5 font-inter text-base">
Expand All @@ -47,7 +47,7 @@ const CategoriesIconCard = ({ topic, withBackground, showCount }) => {
</div>
<div
// style={{ flex: "0 0 3em" }}
className="w-12 h-12 bg-white/90 p-3 my-auto relative rounded-full overflow-hidden"
className="w-12 h-12 bg-gray-100/90 p-3 my-auto relative rounded-full overflow-hidden"
>
{topic.icon?
<img className="w-full h-full" src={topic.icon}/>:<Tag weight="fill" className="my-auto mr-3 opacity-20" size={24}/>}
Expand Down
Loading

0 comments on commit 783ec45

Please sign in to comment.