diff --git a/app/components/ui/button-slide.tsx b/app/components/ui/button-slide.tsx new file mode 100644 index 0000000..10de106 --- /dev/null +++ b/app/components/ui/button-slide.tsx @@ -0,0 +1,24 @@ +import { CarouselNextIcon } from '~/components/icons/carousel-next' +import { CarouselPreviousIcon } from '~/components/icons/carousel-previous' + +type TCarouselButton = { + direction: 'prev' | 'next' + isEnabled: boolean + onClick: () => void +} +export const CarouselButton = ({ + direction, + isEnabled, + onClick, +}: TCarouselButton) => { + const Icon = direction === 'prev' ? CarouselPreviousIcon : CarouselNextIcon + return ( + + ) +} diff --git a/app/components/ui/carousel-hero.tsx b/app/components/ui/carousel-hero.tsx index 54d4211..98394b6 100644 --- a/app/components/ui/carousel-hero.tsx +++ b/app/components/ui/carousel-hero.tsx @@ -1,25 +1,41 @@ import useEmblaCarousel from 'embla-carousel-react' -import { useCallback } from 'react' +import { useCallback, useEffect, useState } from 'react' import { Link } from 'react-router' -import { CarouselNextIcon } from '~/components/icons/carousel-next' -import { CarouselPreviousIcon } from '~/components/icons/carousel-previous' import { Button } from '~/components/ui/button' +import { CarouselButton } from '~/components/ui/button-slide' import { useNewsContext } from '~/contexts/news' import type { TNews } from '~/types/news' export const CarouselHero = (properties: TNews) => { const { setIsSuccessOpen } = useNewsContext() const { title, description, items } = properties - const [emblaReference, emblaApi] = useEmblaCarousel({ loop: true }) + const [emblaReference, emblaApi] = useEmblaCarousel({ loop: false }) + + const [canScrollNext, setCanScrollNext] = useState(false) + const [canScrollPrevious, setCanScrollPrevious] = useState(false) + + const updateButtons = useCallback(() => { + if (emblaApi) { + setCanScrollPrevious(emblaApi.canScrollPrev()) + setCanScrollNext(emblaApi.canScrollNext()) + } + }, [emblaApi]) + + useEffect(() => { + if (emblaApi) { + updateButtons() + emblaApi.on('select', updateButtons) + } + }, [emblaApi, updateButtons]) const previousSlide = useCallback(() => { - if (emblaApi) emblaApi.scrollPrev() - }, [emblaApi]) + if (canScrollPrevious && emblaApi) emblaApi.scrollPrev() + }, [emblaApi, canScrollPrevious]) const nextSlide = useCallback(() => { - if (emblaApi) emblaApi.scrollNext() - }, [emblaApi]) + if (canScrollNext && emblaApi) emblaApi.scrollNext() + }, [emblaApi, canScrollNext]) return (
@@ -33,18 +49,14 @@ export const CarouselHero = (properties: TNews) => {

- -
diff --git a/app/components/ui/carousel-section.tsx b/app/components/ui/carousel-section.tsx index a348b91..9018174 100644 --- a/app/components/ui/carousel-section.tsx +++ b/app/components/ui/carousel-section.tsx @@ -1,25 +1,46 @@ import useEmblaCarousel from 'embla-carousel-react' -import { useCallback } from 'react' +import { useCallback, useEffect, useState } from 'react' import { Link } from 'react-router' -import { CarouselNextIcon } from '~/components/icons/carousel-next' -import { CarouselPreviousIcon } from '~/components/icons/carousel-previous' import { Button } from '~/components/ui/button' +import { CarouselButton } from '~/components/ui/button-slide' import { useNewsContext } from '~/contexts/news' import type { TNews } from '~/types/news' export const CarouselSection = (properties: TNews) => { const { setIsSuccessOpen } = useNewsContext() const { title, description, items } = properties - const [emblaReference, emblaApi] = useEmblaCarousel({ loop: false }) + const [emblaReference, emblaApi] = useEmblaCarousel({ + loop: false, + slidesToScroll: 1, + align: 'start', + }) + + const [canScrollNext, setCanScrollNext] = useState(false) + const [canScrollPrevious, setCanScrollPrevious] = useState(false) + + const updateButtons = useCallback(() => { + if (emblaApi) { + setCanScrollPrevious(emblaApi.canScrollPrev()) + setCanScrollNext(emblaApi.canScrollNext()) + } + }, [emblaApi]) + + useEffect(() => { + if (emblaApi) { + updateButtons() + emblaApi.on('select', updateButtons) + } + }, [emblaApi, updateButtons]) const previousSlide = useCallback(() => { - if (emblaApi) emblaApi.scrollPrev() - }, [emblaApi]) + if (canScrollPrevious && emblaApi) emblaApi.scrollPrev() + }, [emblaApi, canScrollPrevious]) const nextSlide = useCallback(() => { - if (emblaApi) emblaApi.scrollNext() - }, [emblaApi]) + if (canScrollNext && emblaApi) emblaApi.scrollNext() + }, [emblaApi, canScrollNext]) + return (
@@ -33,18 +54,14 @@ export const CarouselSection = (properties: TNews) => {
- -