Touch Events (swipe) using Stimulus

This article was originally published on Rails Designer The time you build and design web-apps for the desktop, without touch events, has been long gone. Users expect features to work on their touch devices (phones, tablets) just as well. In this article I want to explore two features where touch events can be used: (image) carousels; tinder-like, left- and right card swipes. Something like this (view the gif in all its glory on the original article): (don't hate for disliking the first cat!) Because there is a lot of overlap with these two features I am also going to explore inheritance, meaning one Stimulus controller inherits functionality from another class (just like Ruby's UsersController < ApplicationController). As most of the time with such features, let's start with the HTML as it helps to guide what functionality is needed (this HTML is using Tailwind CSS, but that is optional): Previous Next Easy enough, right? The HTML is already telling pretty much how the carousel controller will look like: import { Controller } from "@hotwired/stimulus" export default class extends Controller { static targets = ["container", "slide"] static values = { index: { type: Number, default: 0 } } next() { this.indexValue = (this.indexValue + 1) % this.totalSlides } previous() { this.indexValue = (this.indexValue - 1 + this.totalSlides) % this.totalSlides } // private indexValueChanged() { const offset = this.indexValue * -100 this.containerTarget.style.transform = `translateX(${offset}%)` } get totalSlides() { return this.slideTargets.length } } The next and previous methods handle circular navigation in the carousel where ⁠next increments the indexValue and ⁠previous decrements it, both using the modulo operator (⁠%) with ⁠the value from totalSlides to wrap around to the beginning/end, so the indexValue always stays within valid bounds (0 to totalSlides - 1). Feel like JavaScript concepts like modulo is still going over your head? Check out JavaScript For Rails Developers.

Mar 27, 2025 - 19:17
 0
Touch Events (swipe) using Stimulus

This article was originally published on Rails Designer

The time you build and design web-apps for the desktop, without touch events, has been long gone. Users expect features to work on their touch devices (phones, tablets) just as well.

In this article I want to explore two features where touch events can be used:

  • (image) carousels;
  • tinder-like, left- and right card swipes.

Something like this (view the gif in all its glory on the original article):

Image description

Image description

(don't hate for disliking the first cat!)

Because there is a lot of overlap with these two features I am also going to explore inheritance, meaning one Stimulus controller inherits functionality from another class (just like Ruby's UsersController < ApplicationController).

As most of the time with such features, let's start with the HTML as it helps to guide what functionality is needed (this HTML is using Tailwind CSS, but that is optional):

 data-controller="carousel" data-carousel-index-value="0" class="relative w-full max-w-lg mx-auto">
   class="overflow-hidden">
     data-carousel-target="container" class="flex transition-transform duration-300">
       data-carousel-target="slide" class="w-full shrink-0">
         src="https://unsplash.com/photos/NRQV-hBF10M/download?ixid=M3wxMjA3fDB8MXxhbGx8fHx8fHx8fHwxNzQyNzc0MDI4fA&force=true&w=640" alt="body of water surrounded by trees" class="object-cover w-full h-64">
      

       data-carousel-target="slide" class="w-full shrink-0">
         src="https://unsplash.com/photos/1Z2niiBPg5A/download?ixid=M3wxMjA3fDB8MXxhbGx8fHx8fHx8fHwxNzQyNzg4MDM2fA&force=true&w=640" alt="foggy mountain summit" class="object-cover w-full h-64">
      

       data-carousel-target="slide" class="w-full shrink-0">
         src="https://unsplash.com/photos/78A265wPiO4/download?ixid=M3wxMjA3fDB8MXxhbGx8fHx8fHx8fHwxNzQyNzg1NzQyfA&force=true&w=640" alt="landscape photography of mountain hit by sun rays" class="object-cover w-full h-64">
      
    
  
class="flex justify-between mt-4"> data-action="carousel#previous" class="px-4 py-2 bg-gray-200 rounded hover:bg-gray-300"> Previous data-action="carousel#next" class="px-4 py-2 bg-gray-200 rounded hover:bg-gray-300"> Next