Search code examples
reactjstypescriptcarousel

How to add custom arrow buttons to Alice-Carousel?


I am making a carousel component with alice-carousel (https://github.com/maxmarinich/react-alice-carousel/blob/master/README.md) but having trouble customising the arrows. Code as follows

export const Carousel: React.FC<CarouselProps> = ({text }) => {
  const [activeIndex, setActiveIndex] = useState(0);

  const items = ["item1","item2","item3"]


  const slidePrev = () => {
    activeIndex==0?(
      setActiveIndex(items.length-1)):
    setActiveIndex(activeIndex - 2);
            };

  const slideNext = () => {
    activeIndex==items.length-1?(
      setActiveIndex(0))
        : setActiveIndex(activeIndex + 2)

  };


return(
  <div className="grid grid-cols-3">
    <div className="col-span-2>
    {text}
    </div>
  <div className="flex justify-end">
            <button className="px-8" onClick={slidePrev}><ArrowL/></button>
            <button className="px-8" onClick={slideNext}><ArrowR/></button>
        </div>
<div className="col-span-3 px-10">
    <AliceCarousel
        mouseTracking
        disableDotsControls
        disableButtonsControls
        activeIndex={activeIndex}
        items={items}
        responsive={responsive}
        controlsStrategy="responsive"
        autoPlay={true}
        autoPlayInterval={5000}
        infinite={true}
        keyboardNavigation={true}

    />
    </div>
    </div>

)}

Above code changes the activeIndex therefore changing the items display order but it does so without the "slide" animation. I've looked at examples provided in the library used however cant seem to get it to slide smoothly. What am I doing wrong?


Solution

  • I encourage you to use the library's options to reduce the complexity of your implementation and stop unwanted behavior.

    According to the documentation, there are two functions renderPrevButton and renderNextButton with the AliceCarousel to render your custom component (any elements, icons, buttons, ...) for the Prev and Next item on the gallery.

    So, instead of defining a custom button with a custom action handler, pass your desired component to the mentioned function and give them some styles for customization.

    export const Carousel: React.FC<CarouselProps> = ({text}) => {
    
      const items = ["item1","item2","item3"]
    
      return (
        <div className="grid grid-cols-3">
          <div className="col-span-2">   // ---> you forgot to add closing string quotation mark
            {text}
          </div>
          <div className="col-span-3 px-10">
            <AliceCarousel
              mouseTracking
              disableDotsControls
              // disableButtonsControls  // ---> also remove this
              // activeIndex={activeIndex}  // ---> no need to this anymore
              items={items}
              responsive={responsive}
              controlsStrategy="responsive"
              autoPlay={true}
              autoPlayInterval={5000}
              infinite={true}
              keyboardNavigation={true}
              renderPrevButton={() => {
                return <p className="p-4 absolute left-0 top-0">Previous Item</p>
              }}
              renderNextButton={() => {
                return <p className="p-4 absolute right-0 top-0">Next Item</p>
              }}
            />
          </div>
        </div>
        )
    }
    

    Note: you need to remove the disableButtonsControls option from the AliceCarousel to handle the custom buttons properly. also, you don't need to use the activeIndex option anymore since the carousel will handle them automatically.

    As a sample, I passed a p element with my renderPrevButton without any onClick action. you can define your custom icon, image, or any element and passed them.