diff --git a/src/components/Carousel/example/index.tsx b/src/components/Carousel/example/index.tsx deleted file mode 100644 index c6c5023..0000000 --- a/src/components/Carousel/example/index.tsx +++ /dev/null @@ -1,15 +0,0 @@ -// Proposta do exemplo: Mostrar o clássico funcionamento de um carrosel. -// Em síntese, a mudança de imagens se dá por meio setas ou por meio de -// botões de navegação encontrados na parte inferior. - -import React from "react"; -import { Carousel } from ".."; -import { images } from "./images"; - -export function CarouselExample() { - return ( -
- -
- ); -} diff --git a/src/components/Carousel/example/images.tsx b/src/components/Carousel/example1/images.tsx similarity index 80% rename from src/components/Carousel/example/images.tsx rename to src/components/Carousel/example1/images.tsx index 9364c7a..2c9bdc5 100644 --- a/src/components/Carousel/example/images.tsx +++ b/src/components/Carousel/example1/images.tsx @@ -3,15 +3,18 @@ export const images = [ id: 0, url: "./Images/Cavalinho1.jpg", alt: "Cavalinho 1", + link: "https://struct.unb.br/", }, { id: 1, url: "./Images/Cavalinho2.jpeg", alt: "Cavalinho 2", + link: "", }, { id: 2, url: "./Images/Cavalinho3.png", alt: "Cavalinho 3", + link: "", }, ]; diff --git a/src/components/Carousel/example1/index.tsx b/src/components/Carousel/example1/index.tsx new file mode 100644 index 0000000..af33ebb --- /dev/null +++ b/src/components/Carousel/example1/index.tsx @@ -0,0 +1,27 @@ +// Proposta do exemplo: Mostrar o clássico funcionamento de um carrosel. +// O codigo pode ser alterado para definir quais das propriedades abaixo sera utilizadas: +// - autoplayTime: as imagens passam sozinhas apos a quantidade de segundos indicada, para nao utilizar basta nao passar o prop +// - infiniteLoop: apos a ultima imagem volta para primeira +// - showArrows: define se as setas serao utilizadas ou nao +// - showNavgation: define se os botoes da navegacao irao aparecer embaixo das imagens +// - enableSwipe: define se as imagens podem ser passadas ao arrasta-las + +// O exemplo abaixo é um carrossel tradicional com as setas e os botoes de navegacao + +import React from "react"; +import { Carousel } from ".."; +import { images } from "./images"; + +export function CarouselExample() { + return ( +
+ +
+ ); +} diff --git a/src/components/Carousel/example2/images.tsx b/src/components/Carousel/example2/images.tsx new file mode 100644 index 0000000..2c9bdc5 --- /dev/null +++ b/src/components/Carousel/example2/images.tsx @@ -0,0 +1,20 @@ +export const images = [ + { + id: 0, + url: "./Images/Cavalinho1.jpg", + alt: "Cavalinho 1", + link: "https://struct.unb.br/", + }, + { + id: 1, + url: "./Images/Cavalinho2.jpeg", + alt: "Cavalinho 2", + link: "", + }, + { + id: 2, + url: "./Images/Cavalinho3.png", + alt: "Cavalinho 3", + link: "", + }, +]; diff --git a/src/components/Carousel/example2/index.tsx b/src/components/Carousel/example2/index.tsx new file mode 100644 index 0000000..84be8e6 --- /dev/null +++ b/src/components/Carousel/example2/index.tsx @@ -0,0 +1,29 @@ +// Proposta do exemplo: Mostrar o clássico funcionamento de um carrosel. +// O codigo pode ser alterado para definir quais das propriedades abaixo sera utilizadas: +// - autoplayTime: as imagens passam sozinhas apos a quantidade de segundos indicada, para nao utilizar basta nao passar o prop +// - infiniteLoop: apos a ultima imagem volta para primeira +// - showArrows: define se as setas serao utilizadas ou nao +// - showNavgation: define se os botoes da navegacao irao aparecer embaixo das imagens +// - enableSwipe: define se as imagens podem ser passadas ao arrasta-las + +// O exemplo abaixo é um carrossel sem controle, as imagens passam sozinha +// e quando chegam a ultima volta para primeira + +import React from "react"; +import { Carousel } from ".."; +import { images } from "./images"; + +export function CarouselExample() { + return ( +
+ +
+ ); +} diff --git a/src/components/Carousel/example3/images.tsx b/src/components/Carousel/example3/images.tsx new file mode 100644 index 0000000..2c9bdc5 --- /dev/null +++ b/src/components/Carousel/example3/images.tsx @@ -0,0 +1,20 @@ +export const images = [ + { + id: 0, + url: "./Images/Cavalinho1.jpg", + alt: "Cavalinho 1", + link: "https://struct.unb.br/", + }, + { + id: 1, + url: "./Images/Cavalinho2.jpeg", + alt: "Cavalinho 2", + link: "", + }, + { + id: 2, + url: "./Images/Cavalinho3.png", + alt: "Cavalinho 3", + link: "", + }, +]; diff --git a/src/components/Carousel/example3/index.tsx b/src/components/Carousel/example3/index.tsx new file mode 100644 index 0000000..e02c30a --- /dev/null +++ b/src/components/Carousel/example3/index.tsx @@ -0,0 +1,28 @@ +// Proposta do exemplo: Mostrar o clássico funcionamento de um carrosel. +// O codigo pode ser alterado para definir quais das propriedades abaixo sera utilizadas: +// - autoplayTime: as imagens passam sozinhas apos a quantidade de segundos indicada, para nao utilizar basta nao passar o prop +// - infiniteLoop: apos a ultima imagem volta para primeira +// - showArrows: define se as setas serao utilizadas ou nao +// - showNavgation: define se os botoes da navegacao irao aparecer embaixo das imagens +// - enableSwipe: define se as imagens podem ser passadas ao arrasta-las + +// O exemplo abaixo é um carrossel que as imagens passam sozinhas ou ao clicar nos botoes de navegacao + +import React from "react"; +import { Carousel } from ".."; +import { images } from "./images"; + +export function CarouselExample() { + return ( +
+ +
+ ); +} diff --git a/src/components/Carousel/example4/images.tsx b/src/components/Carousel/example4/images.tsx new file mode 100644 index 0000000..2c9bdc5 --- /dev/null +++ b/src/components/Carousel/example4/images.tsx @@ -0,0 +1,20 @@ +export const images = [ + { + id: 0, + url: "./Images/Cavalinho1.jpg", + alt: "Cavalinho 1", + link: "https://struct.unb.br/", + }, + { + id: 1, + url: "./Images/Cavalinho2.jpeg", + alt: "Cavalinho 2", + link: "", + }, + { + id: 2, + url: "./Images/Cavalinho3.png", + alt: "Cavalinho 3", + link: "", + }, +]; diff --git a/src/components/Carousel/example4/index.tsx b/src/components/Carousel/example4/index.tsx new file mode 100644 index 0000000..646ddfd --- /dev/null +++ b/src/components/Carousel/example4/index.tsx @@ -0,0 +1,27 @@ +// Proposta do exemplo: Mostrar o clássico funcionamento de um carrosel. +// O codigo pode ser alterado para definir quais das propriedades abaixo sera utilizadas: +// - autoplayTime: as imagens passam sozinhas apos a quantidade de segundos indicada, para nao utilizar basta nao passar o prop +// - infiniteLoop: apos a ultima imagem volta para primeira +// - showArrows: define se as setas serao utilizadas ou nao +// - showNavgation: define se os botoes da navegacao irao aparecer embaixo das imagens +// - enableSwipe: define se as imagens podem ser passadas ao arrasta-las + +// O exemplo abaixo é um carrossel que as imagens são passadas ao serem arrastadas ou usando os botoes de navegacao + +import React from "react"; +import { Carousel } from ".."; +import { images } from "./images"; + +export function CarouselExample() { + return ( +
+ +
+ ); +} diff --git a/src/components/Carousel/index.tsx b/src/components/Carousel/index.tsx index 77f14e9..7333a83 100644 --- a/src/components/Carousel/index.tsx +++ b/src/components/Carousel/index.tsx @@ -4,74 +4,180 @@ // -> Chame a função Carousel, passando como argumento seu array criado. // -> Agora basta estilizar o carrosel do seu jeito. -import React, { useState } from "react"; +import React, { useEffect, useState } from "react"; import { ArrowLeft, ArrowRight } from "./svgs"; type Image = { id: number; url: string; alt: string; + link: string; }; type Props = { images: Image[]; + autoplayTime?: number; // Define a quantidade de segundos para as imagens passarem sozinhas (0 para nao passarem) + infiniteLoop: boolean; // Define se o ciclo infinito sera utilizado ou nao (volta para primeira imagem, apos a ultima) + showArrows: boolean; // Define se as setas serao utilizadas ou nao + showNavigation: boolean; // Define se os botoes da navegacao irao aparecer embaixo das imagens + enableSwipe: boolean; // Define se as imagens podem ser passadas ao arrasta-las }; -export function Carousel({ images }: Props) { +export function Carousel({ + images, + autoplayTime = 0, + infiniteLoop, + showArrows, + showNavigation, + enableSwipe, +}: Props) { const [currentPosition, setCurrentPosition] = useState(0); + const [touchStartX, setTouchStartX] = useState(0); + const [mouseStartX, setMouseStartX] = useState(0); + let interval: NodeJS.Timeout; + + useEffect(() => { + if (autoplayTime > 0) { + interval = setInterval(() => { + nextIndex(); + }, autoplayTime * 1000); + } else { + clearInterval(interval); + } + + return () => { + clearInterval(interval); + }; + }, [autoplayTime, currentPosition]); function changePosition(nextPosition: number) { if (nextPosition >= images.length) { - return; + return infiniteLoop ? 0 : currentPosition; } if (nextPosition < 0) { - return; + return infiniteLoop ? images.length - 1 : currentPosition; } - setCurrentPosition(nextPosition); + return nextPosition; } - const nextIndex = () => changePosition(currentPosition + 1); + const nextIndex = () => { + setCurrentPosition(changePosition(currentPosition + 1)); + }; - const prevIndex = () => changePosition(currentPosition - 1); + const prevIndex = () => { + setCurrentPosition(changePosition(currentPosition - 1)); + }; - const moveDot = (toPosition: number) => changePosition(toPosition); + const moveDot = (toPosition: number) => { + setCurrentPosition(changePosition(toPosition)); + }; + + const handleClick = (link: string) => { + window.open(link, "_blank"); + }; return ( -
- - +
{ + if (enableSwipe && event.touches[0]) { + setTouchStartX(event.touches[0].clientX); + } + }} + onTouchMove={(event) => { + if (enableSwipe) { + event.preventDefault(); + } + }} + onTouchEnd={(event) => { + if (enableSwipe && event.changedTouches[0]) { + const touchEndX = event.changedTouches[0].clientX; + if (touchEndX < touchStartX) { + nextIndex(); + } else if (touchEndX > touchStartX) { + prevIndex(); + } + } + }} + onMouseDown={(event) => { + if (enableSwipe) { + setMouseStartX(event.clientX); + } + }} + onMouseMove={(event) => { + if (enableSwipe) { + event.preventDefault(); + } + }} + onMouseUp={(event) => { + if (enableSwipe) { + let mouseEndX = event.clientX; + const diff = mouseEndX - mouseStartX; + const threshold = 50; // Define o intervalo entre a posicao inicial e final do mouse para arrastar + + if (Math.abs(diff) > threshold) { + if (diff < 0) { + nextIndex(); + } else { + prevIndex(); + } + } + + setMouseStartX(0); + mouseEndX = 0; + } + }} + > + {showArrows ? ( + <> + + + + ) : ( + <> + )} {images.map((image, index) => (
- {index === currentPosition && {image.alt}} + {index === currentPosition && ( + {image.alt} image.link && handleClick(image.link)} + style={{ cursor: image.link ? "pointer" : "default" }} + className="select-none" + /> + )}
))} -
- {images.map((image, index) => ( -
+ aria-label={`show ${image.alt}`} + key={image.id} + /> + ))} +
+ ) : ( + <> + )}
); }