mirror of
https://github.com/mue/mue.git
synced 2026-07-10 22:14:39 +02:00
fix: commence work on welcome modal
This commit is contained in:
60
src/components/helpers/carousel/Carousel.jsx
Normal file
60
src/components/helpers/carousel/Carousel.jsx
Normal file
@@ -0,0 +1,60 @@
|
||||
import React, { useState, useEffect, useCallback, useRef } from 'react';
|
||||
import { PrevButton, NextButton } from './CarouselButtons';
|
||||
import useEmblaCarousel from 'embla-carousel-react';
|
||||
import Autoplay from 'embla-carousel-autoplay';
|
||||
import './carousel.scss';
|
||||
import { FaPhotoVideo } from 'react-icons/fa';
|
||||
|
||||
const EmblaCarousel = ({ data, options = { loop: false } }) => {
|
||||
const autoplay = useRef(
|
||||
Autoplay({ delay: 3000, stopOnInteraction: false }, (emblaRoot) => emblaRoot.parentElement),
|
||||
);
|
||||
|
||||
const [emblaRef, emblaApi] = useEmblaCarousel(options, [autoplay.current]);
|
||||
const [prevBtnEnabled, setPrevBtnEnabled] = useState(false);
|
||||
const [nextBtnEnabled, setNextBtnEnabled] = useState(false);
|
||||
|
||||
const scrollNext = useCallback(() => {
|
||||
if (!emblaApi) return;
|
||||
emblaApi.scrollNext();
|
||||
autoplay.current.reset();
|
||||
}, [emblaApi]);
|
||||
|
||||
const scrollPrev = useCallback(() => {
|
||||
if (!emblaApi) return;
|
||||
emblaApi.scrollPrev();
|
||||
autoplay.current.reset();
|
||||
}, [emblaApi]);
|
||||
|
||||
const onSelect = useCallback(() => {
|
||||
if (!emblaApi) return;
|
||||
setPrevBtnEnabled(emblaApi.canScrollPrev());
|
||||
setNextBtnEnabled(emblaApi.canScrollNext());
|
||||
}, [emblaApi]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!emblaApi) return;
|
||||
onSelect();
|
||||
emblaApi.on('select', onSelect);
|
||||
}, [emblaApi, onSelect]);
|
||||
|
||||
return (
|
||||
<div className="embla">
|
||||
<div className="embla__viewport" ref={emblaRef}>
|
||||
<div className="embla__container">
|
||||
{data.map((photo, index) => (
|
||||
<div className="embla__slide" key={index}>
|
||||
<div className="embla__slide__inner">
|
||||
<img className="embla__slide__img" src={photo.url.default} alt="A cool cat." />
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<PrevButton onClick={scrollPrev} enabled={prevBtnEnabled} />
|
||||
<NextButton onClick={scrollNext} enabled={nextBtnEnabled} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default EmblaCarousel;
|
||||
14
src/components/helpers/carousel/CarouselButtons.jsx
Normal file
14
src/components/helpers/carousel/CarouselButtons.jsx
Normal file
@@ -0,0 +1,14 @@
|
||||
import React from 'react';
|
||||
import { MdOutlineArrowForwardIos, MdOutlineArrowBackIos } from 'react-icons/md';
|
||||
|
||||
export const PrevButton = ({ enabled, onClick }) => (
|
||||
<button className="embla__button embla__button--prev" onClick={onClick} disabled={!enabled}>
|
||||
<MdOutlineArrowBackIos />
|
||||
</button>
|
||||
);
|
||||
|
||||
export const NextButton = ({ enabled, onClick }) => (
|
||||
<button className="embla__button embla__button--next" onClick={onClick} disabled={!enabled}>
|
||||
<MdOutlineArrowForwardIos />
|
||||
</button>
|
||||
);
|
||||
88
src/components/helpers/carousel/carousel.scss
Normal file
88
src/components/helpers/carousel/carousel.scss
Normal file
@@ -0,0 +1,88 @@
|
||||
.embla {
|
||||
position: relative;
|
||||
width: 350px;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.embla__viewport {
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.embla__viewport.is-draggable {
|
||||
cursor: move;
|
||||
cursor: grab;
|
||||
}
|
||||
|
||||
.embla__viewport.is-dragging {
|
||||
cursor: grabbing;
|
||||
}
|
||||
|
||||
.embla__container {
|
||||
display: flex;
|
||||
user-select: none;
|
||||
-webkit-touch-callout: none;
|
||||
-khtml-user-select: none;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
margin-left: -10px;
|
||||
}
|
||||
|
||||
.embla__slide {
|
||||
position: relative;
|
||||
min-width: 100%;
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
.embla__slide__inner {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
height: 190px;
|
||||
}
|
||||
|
||||
.embla__slide__img {
|
||||
position: absolute;
|
||||
display: block;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
width: auto;
|
||||
min-height: 100%;
|
||||
min-width: 100%;
|
||||
max-width: none;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
.embla__button {
|
||||
outline: 0;
|
||||
cursor: pointer;
|
||||
touch-action: manipulation;
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
border: 0;
|
||||
width: 30px !important;
|
||||
height: 30px !important;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.embla__button:disabled {
|
||||
cursor: default;
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
.embla__button__svg {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.embla__button--prev {
|
||||
left: 27px;
|
||||
}
|
||||
|
||||
.embla__button--next {
|
||||
right: 27px;
|
||||
}
|
||||
Reference in New Issue
Block a user