<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Yifan Ai</title>
    <description>The latest articles on DEV Community by Yifan Ai (@yifanai).</description>
    <link>https://dev.to/yifanai</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F613675%2F553500d1-546e-4dad-9d97-3d6a7927062c.jpeg</url>
      <title>DEV Community: Yifan Ai</title>
      <link>https://dev.to/yifanai</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/yifanai"/>
    <language>en</language>
    <item>
      <title>React Carousel Component "with Batteries Included"</title>
      <dc:creator>Yifan Ai</dc:creator>
      <pubDate>Sat, 28 Jan 2023 14:35:28 +0000</pubDate>
      <link>https://dev.to/yifanai/react-carousel-component-with-batteries-included-42i1</link>
      <guid>https://dev.to/yifanai/react-carousel-component-with-batteries-included-42i1</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F011t8m65z03btzcrsuun.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F011t8m65z03btzcrsuun.gif" alt="react-gallery-carousel controlled by touch" width="1024" height="1024"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;GitHub: &lt;a href="https://github.com/yifaneye/react-gallery-carousel" rel="noopener noreferrer"&gt;https://github.com/yifaneye/react-gallery-carousel&lt;/a&gt;&lt;br&gt;
Demo: &lt;a href="https://yifaneye.github.io/react-gallery-carousel/" rel="noopener noreferrer"&gt;https://yifaneye.github.io/react-gallery-carousel/&lt;/a&gt; (or &lt;a href="https://yifanai.com/rgc" rel="noopener noreferrer"&gt;https://yifanai.com/rgc&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fstq3kvc47cfjb0c2fgz7.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fstq3kvc47cfjb0c2fgz7.jpg" alt="react-gallery-carousel cover image" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Background
&lt;/h2&gt;

&lt;p&gt;I have &lt;strong&gt;used and carefully analysed a lot of carousel/slider components&lt;/strong&gt;. I summarised that &lt;strong&gt;their issues&lt;/strong&gt; are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Some of them do not move the slide as the user swipes on the slide.&lt;/li&gt;
&lt;li&gt;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.&lt;/li&gt;
&lt;li&gt;Most of them do not support keyboard navigation (i.e. left, right and tab key).&lt;/li&gt;
&lt;li&gt;Most of them cannot be maximised 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.&lt;/li&gt;
&lt;li&gt;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.&lt;/li&gt;
&lt;li&gt;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.&lt;/li&gt;
&lt;li&gt;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.&lt;/li&gt;
&lt;li&gt;Most of them do not respect the reduced motion settings by the user.&lt;/li&gt;
&lt;li&gt;Most of them disregard the velocity of the swipe and just set a constant transition duration.&lt;/li&gt;
&lt;li&gt;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.&lt;/li&gt;
&lt;li&gt;Most of them do not support custom elements in a slide.&lt;/li&gt;
&lt;li&gt;Most of them cannot be set to display in Right-to-Left (RTL).&lt;/li&gt;
&lt;li&gt;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.&lt;/li&gt;
&lt;li&gt;Some of them will cause the slides to stuck its position on window resize or on mobile device orientation change, until another user interaction.&lt;/li&gt;
&lt;li&gt;Some of them can only have predetermined images (i.e. before the carousel component mounts).&lt;/li&gt;
&lt;li&gt;Most of them do not provide a solution for fallback image (for when an image is not available).&lt;/li&gt;
&lt;li&gt;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.&lt;/li&gt;
&lt;li&gt;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.&lt;/li&gt;
&lt;li&gt;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.&lt;/li&gt;
&lt;li&gt;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.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;⬇️&lt;/p&gt;

&lt;p&gt;I wanted to write my own &lt;strong&gt;detail-oriented&lt;/strong&gt; and &lt;strong&gt;exquisite&lt;/strong&gt; carousel component that is easy to use yet solves/supports all these things above under the hood. 🤓&lt;/p&gt;

&lt;p&gt;I wanted to take my understanding of JavaScript events, DOM manipulation, browser APIs, cross-browser compatibility and performance debugging to the next level. 🤓&lt;/p&gt;

&lt;p&gt;I wanted to master React functional components, hooks, custom hooks and reconciliation. 🤓&lt;/p&gt;

&lt;p&gt;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 &lt;a href="https://www.w3.org/WAI/tutorials/carousels/" rel="noopener noreferrer"&gt;W3C accessible carousel tutorials&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;⬇️&lt;/p&gt;

&lt;p&gt;My carousel should support: touch, mouse emulation, keyboard navigation, modal (lightbox), thumbnails, autoplay (and auto pause), RTL (right to left for internationalisation), 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, customisation and great accessibility. 😎&lt;/p&gt;

&lt;p&gt;(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. ✅&lt;br&gt;
It should also be able to detect a mostly horizontal swipe and then fix the carousel vertically in the page. ✅)&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;Demo: &lt;a href="https://yifaneye.github.io/react-gallery-carousel/" rel="noopener noreferrer"&gt;https://yifaneye.github.io/react-gallery-carousel/&lt;/a&gt; (or &lt;a href="https://yifanai.com/rgc" rel="noopener noreferrer"&gt;https://yifanai.com/rgc&lt;/a&gt;)&lt;br&gt;
GitHub: &lt;a href="https://github.com/yifaneye/react-gallery-carousel" rel="noopener noreferrer"&gt;https://github.com/yifaneye/react-gallery-carousel&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F011t8m65z03btzcrsuun.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F011t8m65z03btzcrsuun.gif" alt="react-gallery-carousel controlled by touch" width="1024" height="1024"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fub9fzr0b4ai282yc6gm9.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fub9fzr0b4ai282yc6gm9.gif" alt="react-gallery-carousel controlled by mouse" width="8" height="8"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F276qa3q3wp32kldmla1p.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F276qa3q3wp32kldmla1p.jpg" alt="Lighthouse report on react-gallery-carousel's demo site" width="800" height="465"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Demo: &lt;a href="https://yifaneye.github.io/react-gallery-carousel/" rel="noopener noreferrer"&gt;https://yifaneye.github.io/react-gallery-carousel/&lt;/a&gt; (or &lt;a href="https://yifanai.com/rgc" rel="noopener noreferrer"&gt;https://yifanai.com/rgc&lt;/a&gt;)&lt;br&gt;
npm: &lt;a href="https://www.npmjs.com/package/react-gallery-carousel" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/react-gallery-carousel&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I carefully handcrafted icons, wrote many useful custom hooks and wrote many exquisite functional components to complete this piece of work. 👨🏻‍💻&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjdca9cuhc6k0tdv63fbn.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjdca9cuhc6k0tdv63fbn.jpg" alt="react-gallery-carousel not maximised" width="800" height="798"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fybiz9r1cl6iqxookin3r.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fybiz9r1cl6iqxookin3r.jpg" alt="react-gallery-carousel being maximised" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Everyone is welcome to come and ask questions, find and report issues, make pull requests and suggestions! 😊&lt;/p&gt;

&lt;p&gt;GitHub: &lt;a href="https://github.com/yifaneye/react-gallery-carousel" rel="noopener noreferrer"&gt;https://github.com/yifaneye/react-gallery-carousel&lt;/a&gt;&lt;br&gt;
Demo: &lt;a href="https://yifaneye.github.io/react-gallery-carousel/" rel="noopener noreferrer"&gt;https://yifaneye.github.io/react-gallery-carousel/&lt;/a&gt; (or &lt;a href="https://yifanai.com/rgc" rel="noopener noreferrer"&gt;https://yifanai.com/rgc&lt;/a&gt;)&lt;br&gt;
Buy me a coffee to support me: &lt;a href="https://www.buymeacoffee.com/yifanai" rel="noopener noreferrer"&gt;https://www.buymeacoffee.com/yifanai&lt;/a&gt;&lt;/p&gt;

</description>
      <category>welcome</category>
    </item>
    <item>
      <title>Carousel Component 🎠 That Solves 20 Common Issues</title>
      <dc:creator>Yifan Ai</dc:creator>
      <pubDate>Sat, 08 May 2021 13:06:57 +0000</pubDate>
      <link>https://dev.to/yifanai/carousel-component-that-solves-20-common-issues-b1e</link>
      <guid>https://dev.to/yifanai/carousel-component-that-solves-20-common-issues-b1e</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F011t8m65z03btzcrsuun.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F011t8m65z03btzcrsuun.gif" alt="react-gallery-carousel controlled by touch"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;GitHub: &lt;a href="https://github.com/yifaneye/react-gallery-carousel" rel="noopener noreferrer"&gt;https://github.com/yifaneye/react-gallery-carousel&lt;/a&gt;&lt;br&gt;
Demo: &lt;a href="https://yifaneye.github.io/react-gallery-carousel/" rel="noopener noreferrer"&gt;https://yifaneye.github.io/react-gallery-carousel/&lt;/a&gt; (or &lt;a href="https://yifanai.com/rgc" rel="noopener noreferrer"&gt;https://yifanai.com/rgc&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fstq3kvc47cfjb0c2fgz7.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fstq3kvc47cfjb0c2fgz7.jpg" alt="react-gallery-carousel cover image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Background
&lt;/h1&gt;

&lt;p&gt;I have &lt;strong&gt;used and carefully analyzed a lot of carousel/slider components&lt;/strong&gt;. I summarized that &lt;strong&gt;their issues&lt;/strong&gt; are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Some of them do not move the slide as the user swipes on the slide.&lt;/li&gt;
&lt;li&gt;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.&lt;/li&gt;
&lt;li&gt;Most of them do not support keyboard navigation (i.e. left, right and tab key).&lt;/li&gt;
&lt;li&gt;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.&lt;/li&gt;
&lt;li&gt;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.&lt;/li&gt;
&lt;li&gt;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.&lt;/li&gt;
&lt;li&gt;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.&lt;/li&gt;
&lt;li&gt;Most of them do not respect the reduced motion settings by the user.&lt;/li&gt;
&lt;li&gt;Most of them disregard the velocity of the swipe and just set a constant transition duration.&lt;/li&gt;
&lt;li&gt;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.&lt;/li&gt;
&lt;li&gt;Most of them do not support custom elements in a slide.&lt;/li&gt;
&lt;li&gt;Most of them cannot be set to display in Right-to-Left (RTL).&lt;/li&gt;
&lt;li&gt;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.&lt;/li&gt;
&lt;li&gt;Some of them will cause the slides to stuck its position on window resize or on mobile device orientation change, until another user interaction.&lt;/li&gt;
&lt;li&gt;Some of them can only have predetermined images (i.e. before the carousel component mounts).&lt;/li&gt;
&lt;li&gt;Most of them do not provide a solution for fallback image (for when an image is not available).&lt;/li&gt;
&lt;li&gt;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.&lt;/li&gt;
&lt;li&gt;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.&lt;/li&gt;
&lt;li&gt;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.&lt;/li&gt;
&lt;li&gt;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.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;⬇️&lt;/p&gt;

&lt;p&gt;I wanted to write my own &lt;strong&gt;detail-oriented&lt;/strong&gt; and &lt;strong&gt;exquisite&lt;/strong&gt; carousel component that is easy to use yet solves/supports all these things above under the hood. 🤓&lt;/p&gt;

&lt;p&gt;I wanted to take my understanding of JavaScript events, DOM manipulation, browser APIs, cross-browser compatibility and performance debugging to the next level. 🤓&lt;/p&gt;

&lt;p&gt;I wanted to master React functional components, hooks, custom hooks and reconciliation. 🤓&lt;/p&gt;

&lt;p&gt;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 &lt;a href="https://www.w3.org/WAI/tutorials/carousels/" rel="noopener noreferrer"&gt;W3C accessible carousel tutorials&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;⬇️&lt;/p&gt;

&lt;p&gt;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. 😎&lt;/p&gt;

&lt;p&gt;(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. ✅&lt;br&gt;
It should also be able to detect a mostly horizontal swipe and then fix the carousel vertically in the page. ✅)&lt;/p&gt;

&lt;h1&gt;
  
  
  Demo
&lt;/h1&gt;

&lt;p&gt;Demo: &lt;a href="https://yifaneye.github.io/react-gallery-carousel/" rel="noopener noreferrer"&gt;https://yifaneye.github.io/react-gallery-carousel/&lt;/a&gt; (or &lt;a href="https://yifanai.com/rgc" rel="noopener noreferrer"&gt;https://yifanai.com/rgc&lt;/a&gt;)&lt;br&gt;
GitHub: &lt;a href="https://github.com/yifaneye/react-gallery-carousel" rel="noopener noreferrer"&gt;https://github.com/yifaneye/react-gallery-carousel&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F011t8m65z03btzcrsuun.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F011t8m65z03btzcrsuun.gif" alt="react-gallery-carousel controlled by touch"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fub9fzr0b4ai282yc6gm9.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fub9fzr0b4ai282yc6gm9.gif" alt="react-gallery-carousel controlled by mouse"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F276qa3q3wp32kldmla1p.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F276qa3q3wp32kldmla1p.jpg" alt="Lighthouse report on react-gallery-carousel's demo site"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Demo: &lt;a href="https://yifaneye.github.io/react-gallery-carousel/" rel="noopener noreferrer"&gt;https://yifaneye.github.io/react-gallery-carousel/&lt;/a&gt; (or &lt;a href="https://yifanai.com/rgc" rel="noopener noreferrer"&gt;https://yifanai.com/rgc&lt;/a&gt;)&lt;br&gt;
npm: &lt;a href="https://www.npmjs.com/package/react-gallery-carousel" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/react-gallery-carousel&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I carefully handcrafted icons, wrote many useful custom hooks and wrote many exquisite functional components to complete this piece of work. 👨🏻‍💻&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjdca9cuhc6k0tdv63fbn.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjdca9cuhc6k0tdv63fbn.jpg" alt="react-gallery-carousel not maximized"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fybiz9r1cl6iqxookin3r.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fybiz9r1cl6iqxookin3r.jpg" alt="react-gallery-carousel being maximized"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Everyone is welcome to come and ask questions, find issues, make pull requests and make suggestions on GitHub! 😊&lt;/p&gt;

&lt;p&gt;GitHub: &lt;a href="https://github.com/yifaneye/react-gallery-carousel" rel="noopener noreferrer"&gt;https://github.com/yifaneye/react-gallery-carousel&lt;/a&gt;&lt;br&gt;
Demo: &lt;a href="https://yifaneye.github.io/react-gallery-carousel/" rel="noopener noreferrer"&gt;https://yifaneye.github.io/react-gallery-carousel/&lt;/a&gt; (or &lt;a href="https://yifanai.com/rgc" rel="noopener noreferrer"&gt;https://yifanai.com/rgc&lt;/a&gt;)&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>css</category>
      <category>webdev</category>
    </item>
    <item>
      <title>My Mobile-friendly, Detail-oriented Carousel 🎠 Component</title>
      <dc:creator>Yifan Ai</dc:creator>
      <pubDate>Sun, 25 Apr 2021 11:57:46 +0000</pubDate>
      <link>https://dev.to/yifanai/my-mobile-friendly-detail-oriented-carousel-component-2k4e</link>
      <guid>https://dev.to/yifanai/my-mobile-friendly-detail-oriented-carousel-component-2k4e</guid>
      <description>&lt;p&gt;GitHub: &lt;a href="https://github.com/yifaneye/react-gallery-carousel" rel="noopener noreferrer"&gt;https://github.com/yifaneye/react-gallery-carousel&lt;/a&gt;&lt;br&gt;
Demo: &lt;a href="https://yifaneye.github.io/react-gallery-carousel/" rel="noopener noreferrer"&gt;https://yifaneye.github.io/react-gallery-carousel/&lt;/a&gt; (or &lt;a href="https://yifanai.com/rgc" rel="noopener noreferrer"&gt;https://yifanai.com/rgc&lt;/a&gt;)&lt;br&gt;
npm: &lt;a href="https://www.npmjs.com/package/react-gallery-carousel" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/react-gallery-carousel&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F011t8m65z03btzcrsuun.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F011t8m65z03btzcrsuun.gif" alt="react-gallery-carousel controlled by touch"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fstq3kvc47cfjb0c2fgz7.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fstq3kvc47cfjb0c2fgz7.jpg" alt="react-gallery-carousel cover image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Background&lt;/p&gt;

&lt;p&gt;The thing is that I have &lt;strong&gt;used and carefully analyzed a lot of other carousel/slider components&lt;/strong&gt;. &lt;strong&gt;I summarized 20 common issues&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Some of them do not move the slide as the user swipes on the slide.&lt;/li&gt;
&lt;li&gt;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.&lt;/li&gt;
&lt;li&gt;Most of them do not support keyboard navigation (i.e. left, right and tab key).&lt;/li&gt;
&lt;li&gt;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.&lt;/li&gt;
&lt;li&gt;Most of them do not have an easy solution for building thumbnails. With the ones those have thumbnails, most of the thumbnails can not be freely scrolled which lead to poor user experience. In addition, most of the thumbnails can not be lazy loaded.&lt;/li&gt;
&lt;li&gt;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.&lt;/li&gt;
&lt;li&gt;Some of them cannot autoplay. With the ones those can autoplay, they can not auto pause. For example, when the user hits another tab or goes to another app, the autoplay on those carousels do not pause.&lt;/li&gt;
&lt;li&gt;Most of them do not respect the reduced motion settings by the user.&lt;/li&gt;
&lt;li&gt;Most of them disregard the velocity of the swipe and just set a constant transition duration.&lt;/li&gt;
&lt;li&gt;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.&lt;/li&gt;
&lt;li&gt;Most of them do not support custom elements in a slide.&lt;/li&gt;
&lt;li&gt;Most of them cannot be set to display in Right-to-Left (RTL).&lt;/li&gt;
&lt;li&gt;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.&lt;/li&gt;
&lt;li&gt;Some of them will cause the slides to stuck its position on window resize or on mobile device orientation change, until another user interaction.&lt;/li&gt;
&lt;li&gt;Some of them can only have predetermined images (i.e. before the carousel component mounts).&lt;/li&gt;
&lt;li&gt;Most of them do not provide a solution for fallback image (for when an image is not available).&lt;/li&gt;
&lt;li&gt;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.&lt;/li&gt;
&lt;li&gt;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.&lt;/li&gt;
&lt;li&gt;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.&lt;/li&gt;
&lt;li&gt;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.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;⬇️&lt;/p&gt;

&lt;p&gt;I wanted to write my own &lt;strong&gt;detail-oriented&lt;/strong&gt; and &lt;strong&gt;exquisite&lt;/strong&gt; carousel component that is easy to use yet solves/supports all these things above under the hood. 🤓&lt;/p&gt;

&lt;p&gt;I wanted to take my understanding of JavaScript events, DOM manipulation, browser APIs, cross-browser compatibility and performance debugging to the next level. 🤓&lt;/p&gt;

&lt;p&gt;I wanted to master React functional components, hooks, custom hooks and reconciliation. 🤓&lt;/p&gt;

&lt;p&gt;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 &lt;a href="https://www.w3.org/WAI/tutorials/carousels/" rel="noopener noreferrer"&gt;W3C accessible carousel tutorials&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;⬇️&lt;/p&gt;

&lt;p&gt;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. 😎&lt;/p&gt;

&lt;p&gt;(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. ✅&lt;br&gt;
It should also be able to detect a mostly horizontal swipe and then fix the carousel vertically in the page. ✅)&lt;/p&gt;

&lt;p&gt;Demo: &lt;a href="https://yifaneye.github.io/react-gallery-carousel/" rel="noopener noreferrer"&gt;https://yifaneye.github.io/react-gallery-carousel/&lt;/a&gt; (or &lt;a href="https://yifanai.com/rgc" rel="noopener noreferrer"&gt;https://yifanai.com/rgc&lt;/a&gt;) 👈&lt;br&gt;
GitHub: &lt;a href="https://github.com/yifaneye/react-gallery-carousel" rel="noopener noreferrer"&gt;https://github.com/yifaneye/react-gallery-carousel&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F011t8m65z03btzcrsuun.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F011t8m65z03btzcrsuun.gif" alt="react-gallery-carousel controlled by touch"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fub9fzr0b4ai282yc6gm9.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fub9fzr0b4ai282yc6gm9.gif" alt="react-gallery-carousel controlled by mouse"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F276qa3q3wp32kldmla1p.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F276qa3q3wp32kldmla1p.jpg" alt="Lighthouse report on react-gallery-carousel's demo site"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;GitHub: &lt;a href="https://github.com/yifaneye/react-gallery-carousel" rel="noopener noreferrer"&gt;https://github.com/yifaneye/react-gallery-carousel&lt;/a&gt; 👈&lt;br&gt;
Demo: &lt;a href="https://yifaneye.github.io/react-gallery-carousel/" rel="noopener noreferrer"&gt;https://yifaneye.github.io/react-gallery-carousel/&lt;/a&gt; (or &lt;a href="https://yifanai.com/rgc" rel="noopener noreferrer"&gt;https://yifanai.com/rgc&lt;/a&gt;)&lt;br&gt;
npm: &lt;a href="https://www.npmjs.com/package/react-gallery-carousel" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/react-gallery-carousel&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I carefully handcrafted icons, wrote many useful custom hooks and wrote many exquisite functional components to complete this piece of work. 👨🏻‍💻&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjdca9cuhc6k0tdv63fbn.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjdca9cuhc6k0tdv63fbn.jpg" alt="react-gallery-carousel not maximized"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fybiz9r1cl6iqxookin3r.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fybiz9r1cl6iqxookin3r.jpg" alt="react-gallery-carousel being maximized"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Everyone is welcome to come and ask questions, find issues, make pull requests and make suggestions on GitHub! 😊&lt;/p&gt;

&lt;p&gt;GitHub: &lt;a href="https://github.com/yifaneye/react-gallery-carousel" rel="noopener noreferrer"&gt;https://github.com/yifaneye/react-gallery-carousel&lt;/a&gt; 👈&lt;br&gt;
Demo: &lt;a href="https://yifaneye.github.io/react-gallery-carousel/" rel="noopener noreferrer"&gt;https://yifaneye.github.io/react-gallery-carousel/&lt;/a&gt; (or &lt;a href="https://yifanai.com/rgc" rel="noopener noreferrer"&gt;https://yifanai.com/rgc&lt;/a&gt;) 👈&lt;br&gt;
npm: &lt;a href="https://www.npmjs.com/package/react-gallery-carousel" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/react-gallery-carousel&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>css</category>
      <category>react</category>
      <category>webdev</category>
    </item>
    <item>
      <title>My "Dependency-Free" Carousel 🎠 Component</title>
      <dc:creator>Yifan Ai</dc:creator>
      <pubDate>Tue, 13 Apr 2021 13:09:15 +0000</pubDate>
      <link>https://dev.to/yifanai/dependency-free-react-carousel-component-36aj</link>
      <guid>https://dev.to/yifanai/dependency-free-react-carousel-component-36aj</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fub9fzr0b4ai282yc6gm9.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fub9fzr0b4ai282yc6gm9.gif" alt="react-gallery-carousel controlled by mouse"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Recently, I completed react-gallery-carousel, a "dependency-free" React carousel component with support for touch, mouse dragging, lazy loading, pinch to zoom, thumbnails, modal and keyboard navigation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F011t8m65z03btzcrsuun.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F011t8m65z03btzcrsuun.gif" alt="react-gallery-carousel controlled by touch"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Demo: &lt;a href="https://yifaneye.github.io/react-gallery-carousel/" rel="noopener noreferrer"&gt;https://yifaneye.github.io/react-gallery-carousel/&lt;/a&gt; (or &lt;a href="https://yifanai.com/rgc" rel="noopener noreferrer"&gt;https://yifanai.com/rgc&lt;/a&gt;) 👈&lt;br&gt;
GitHub: &lt;a href="https://github.com/yifaneye/react-gallery-carousel" rel="noopener noreferrer"&gt;https://github.com/yifaneye/react-gallery-carousel&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F276qa3q3wp32kldmla1p.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F276qa3q3wp32kldmla1p.jpg" alt="Lighthouse report on react-gallery-carousel's demo site"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fub9fzr0b4ai282yc6gm9.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fub9fzr0b4ai282yc6gm9.gif" alt="rgc3"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;react-gallery-carousel component not only supports:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Lazy loading&lt;/li&gt;
&lt;li&gt;Thumbnails&lt;/li&gt;
&lt;li&gt;Maximization (fullscreen)&lt;/li&gt;
&lt;li&gt;Finger swiping and pinch zooming&lt;/li&gt;
&lt;li&gt;Mouse dragging&lt;/li&gt;
&lt;li&gt;Keyboard navigation&lt;/li&gt;
&lt;li&gt;Accessibility&lt;/li&gt;
&lt;li&gt;Instantaneous speed detection;
but also supports customization with props. 😊&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I handcrafted icons, wrote many useful custom hooks and wrote many exquisite functional components to complete this piece of work. 👨🏻‍💻&lt;/p&gt;

&lt;p&gt;Everyone is welcome to ask questions, find issues, make pull requests, make suggestions and give stars on GitHub! 👏&lt;/p&gt;

&lt;p&gt;Demo: &lt;a href="https://yifaneye.github.io/react-gallery-carousel/" rel="noopener noreferrer"&gt;https://yifaneye.github.io/react-gallery-carousel/&lt;/a&gt; (or &lt;a href="https://yifanai.com/rgc" rel="noopener noreferrer"&gt;https://yifanai.com/rgc&lt;/a&gt;) 👈&lt;br&gt;
GitHub: &lt;a href="https://github.com/yifaneye/react-gallery-carousel" rel="noopener noreferrer"&gt;https://github.com/yifaneye/react-gallery-carousel&lt;/a&gt;&lt;br&gt;
npm: &lt;a href="https://www.npmjs.com/package/react-gallery-carousel" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/react-gallery-carousel&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
