I have used and carefully analyzed a lot of carousel/slider components. I summarized that their issues are:
- Some of them do not move the slide as the user swipes on the slide.
- Most of them do not support mouse dragging to move to the previous or the next slide. With the ones those support mouse emulation, some of them do not properly handle the case where the mouse leaves the carousel, which allow the user to continuously control the carousel.
- Most of them do not support keyboard navigation (i.e. left, right and tab key).
- Most of them cannot be maximized to fullscreen/modal/lightbox. With fullscreen, there is the issue of browser compatibility, i.e. iOS Safari on iPhone does not support the fullscreen API.
- Most of them do not have an easy solution for building thumbnails. With the ones those have thumbnails, most of the thumbnails cannot be freely scrolled which lead to poor user experience. In addition, most of the thumbnails cannot be lazy loaded.
- Most of them cannot lazy load (and preload) images. With the ones those can lazy load, most of them have transition that traverses the intermediate images when the user goes to a distant slide, which defeat the purpose of lazy loading.
- Some of them cannot autoplay. With the ones those can autoplay, they cannot auto pause. For example, when the user hits another tab or goes to another app, the autoplay on those carousels do not pause.
- Most of them do not respect the reduced motion settings by the user.
- Most of them disregard the velocity of the swipe and just set a constant transition duration.
- Some of their carousels will be in different sizes when the images/slides inside are in different sizes. Some of their transitions are bumpy when their images/slides are in different sizes.
- Most of them do not support custom elements in a slide.
- Most of them cannot be set to display in Right-to-Left (RTL).
- Some of them disable pinching to zoom, while some others glitch when pinching with 2 fingers. Besides, when the window is zoomed in, most of them still detect for touch swiping to move to the previous, or the next slide, while the intention of most users in this scenario is panning to see other parts of the current slide.
- Some of them will cause the slides to stuck its position on window resize or on mobile device orientation change, until another user interaction.
- Some of them can only have predetermined images (i.e. before the carousel component mounts).
- Most of them do not provide a solution for fallback image (for when an image is not available).
- Some of them get zoomed in when the user double taps on the control, while the intention of most users in this scenario is to quickly go to the next after the next slide.
- Some of them remove the left or right button to indicate that there are no more slides in that direction. However, user is likely to click that spot where the button used to be, which causes undesired behaviours e.g. clicking on a link or button which is also at that spot.
- Some of them use the method of cloning the first, and the last slide to achieve looping (or infinite mode). I think that method is not great semantically.
- Some of them cannot distinguish a vertical swipe from a horizontal swipe, so that a not exactly vertical swipe moves the slides slightly horizontally; and a not exactly horizontal swipe moves the (document) page slightly vertically.
I wanted to write my own detail-oriented and exquisite carousel component that is easy to use yet solves/supports all these things above under the hood. 🤓
I wanted to master React functional components, hooks, custom hooks and reconciliation. 🤓
I wanted to learn more, place more care and attention to accessibility. I want to give focus outlines to the right users, support keyboard navigation, support screen reader, and follow W3C accessible carousel tutorials.
My carousel should support: touch, mouse emulation, keyboard navigation, modal (lightbox), thumbnails, autoplay (and auto pause), RTL (right to left for internationalization), image lazy loading (and preloading), responsive images, fallback image, reduced motion settings, instantaneous velocity detection, responsive design, images with any sizes, custom elements in a slide, pinch to zoom, customization and great accessibility. 😎
(e.g. To solve the last issue (#20) in the list above, my carousel should be able to detect a mostly vertical swipe and then fix the slides horizontally in the carousel. ✅
It should also be able to detect a mostly horizontal swipe and then fix the carousel vertically in the page. ✅)
I carefully handcrafted icons, wrote many useful custom hooks and wrote many exquisite functional components to complete this piece of work. 👨🏻💻
Everyone is welcome to come and ask questions, find issues, make pull requests and make suggestions on GitHub! 😊