-
-
Notifications
You must be signed in to change notification settings - Fork 7k
Description
Describe the bug
Issue
The autoplay plugin has options like stopOnInteraction
, stopOnMouseEnter
, and stopOnFocusIn
but they don't work as intended. Without these options you can get stuck in a loop trying to return to the previous slide as it plays.
I believe this is due to the Shadcn component having the previous and next buttons outside of the carousel container. These options seem to be triggered via events captured on the carousel div itself.
The example of the autoplay plugin in the Shadcn docs uses the mouseEnter
and mouseLeave
props on the carousel component to control autoplay using a ref to the plugin but it doesn't really work the same way. For example, it uses plugin.current.reset
on mouseLeave
(presumably to restart the carousel autoplay) but this function doesn't do anything when autoplay is stopped, which is the case here. From the Embla docs:
reset
"Resets the timer and starts over. This will only take effect if autoplay is already active. If autoplay is stopped, this method won't do anything."
It would be nice to have control over the plugin using the plugin options.
Furthermore, the Shadcn docs say to use the Embla docs but if you follow the Embla docs you can run into all sorts of issues, since these options don't work in the shadcn component. The Shadcn docs say:
See the Embla Carousel docs for more information on using plugins.
Solution
I imagine the solution could be to change where the clicks are captured for the plugin options, or to pass the events from the buttons to the carousel somehow. A alternate is to alter the next and previous components to stop or at least reset the autoplay timer when the buttons are clicked. For example:
// carousel.tsx
function CarouselPrevious({
// ...
const handleClick = () => {
scrollPrev()
const autoplay = api?.plugins()?.autoplay
autoplay?.reset()
}
Affected component/components
Carousel
How to reproduce
- Install shadcn and the Carousel via the CLI and install
embla-carousel-autoplay
- Create a multi-slide carousel with the prop
plugins={[Autoplay({ delay: 2000, stopOnInteraction: true })]}
- Click the previous button and the carousel will not stop playing.
The other issue is reproduced by pasting the autoplay example from the Shadcn docs and hovering the carousel, it will stop but it won't restart when the mouse leaves which I believe is the intended functionality of the onMouseLeave
callback.
Codesandbox/StackBlitz link
https://stackblitz.com/edit/vitejs-vite-bzzhykcp?file=src%2FApp.tsx
Logs
System Info
Apple M1 Pro, macOS Sonoma 14.5, Google Chrome Version 140.0.7339.215
Before submitting
- I've made research efforts and searched the documentation
- I've searched for existing issues