davidjerleke / embla-carousel

A lightweight carousel library with fluid motion and great swipe precision.
https://www.embla-carousel.com
MIT License
5.8k stars 175 forks source link

Align center doesn't work with trimSnap and arrows aren't enabled on the last slide with keepSnaps #313

Closed AnaisLT closed 2 years ago

AnaisLT commented 2 years ago

Bug is related to

embla-carousel-react

Embla Carousel version

Describe the bug

CodeSandbox

Steps to reproduce

  1. On (1) that uses keepSnaps

  2. Select a slide to see it centred

  3. Scroll down to the end of the carousel

  4. The button arrow should show as still enabled

  5. On (2) that uses trimSnaps

  6. Select a slide, the carousel will not centre the slide

  7. But the button arrows are disabled when expected

Expected behavior

davidjerleke commented 2 years ago

Hi @AnaisLT,

Thank you for your bug report. The problem with the buttons being active/inactive is happening because you don't update their states properly. This should work as intended:

  const updatePrevNextButtonState = useCallback(() => {
    if (!embla) return;
    setPrevBtnEnabled(embla.canScrollPrev());
    setNextBtnEnabled(embla.canScrollNext());
  }, [embla]);

  useEffect(() => {
    if (!embla) return;
    embla.on("select", updatePrevNextButtonState); // Set button states when the selected snap changes
    updatePrevNextButtonState(); // Set button states when the carousel mounts
  }, [embla, updatePrevNextButtonState]);

Regarding the containScroll option I think you might be misunderstanding what it does:

Clear leading and trailing empty space that causes excessive scrolling. Use trimSnaps to only use snap points that trigger scrolling or keepSnaps to keep them.

Please take a moment and watch the screen recording below. containScroll will clear leading and trailing space. It will override slide alignments at the beginning and/or the end of the carousel if needed, in order to clear the space and cut any excessive scrolling. It's important that you follow the currentIndex which might bring some clarity on what it actually does.

⚠️ Please note that I accidentally typed keepSnaps where it should say trimSnaps in the video. So the top carousel is trimSnaps, the second is keepSnaps and the last one is without containScroll.

https://user-images.githubusercontent.com/11529148/167492650-ac3e1573-6dc8-485e-bbbd-287b2d66792f.mov

And another thing:

  const [viewportRef, embla] = useEmblaCarousel({
    align: selectedIndex ? "center" : "start", // You might not want to do this
    containScroll: "trimSnaps"
  });

Any changes in options will trigger a hard reset of the carousel. So be sure that you actually want the carousel to stop scrolling and reset with its new options here.

Best, David

AnaisLT commented 2 years ago

Hi David,

Thank you so much for your prompt reply. This is super helpful.

Best, Anais

davidjerleke commented 2 years ago

@AnaisLT did it solve the problem?

Best, David