Jerin A Mathews
Jerin A Mathews

Reputation: 8712

Create carousel cards as in fb messenger in react js

Am developing a chat widget like intercom widget in react js and I want to add carousel cards component, as in facebook messenger.

enter image description here

On mobile, when user swipe one card, the next one should come and center itself, and on the web, there should be a left and right button, which when clicked show respective card.

I searched and couldn't find any packages for this. How can I implement this? Am new to react.

Upvotes: 1

Views: 2423

Answers (3)

Prabu samvel
Prabu samvel

Reputation: 1223

As the other answers, You have the carousel component in react-bootstrap and reactstrap.

Personally, I feel reactstrap have better documentation than react-bootstrap. You can simply found an example for carousel in their official doc. https://reactstrap.github.io/components/carousel/

But, Those example doesn't have the swipe event as you expected and I am also can't find any carousel with swipe event for both web and mobile view. So finally, I have decided to make a custom carousel with the swipe event.

For the web, I have used onDragStart and onDragEnd. And For the mobile view, I used onTouchStart, onTouchMove and onTouchEnd to detect the swipe left and right.

Here the changes.

//Global variables to hold the last and current X-axis positions.
var lastX = 0;
var currentX = 0;

//For web, detect swipe left and right based on mouse drag events. 
handleMouse = e => {
    e.persist();
    let type = e.type.toLowerCase();
    if (type === "dragstart") {
      lastX = e.clientX;
    } else {
      if (lastX === 0 || e.clientX === 0 || lastX === e.clientX) {
        return;
      }
      if (e.clientX > lastX) {
        this.previous();
        console.log("swife right");
      } else {
        this.next();
        console.log("swife left");
      }
    }
  };

  //For mobile, detect swipe left and right based on touch events. 
  handleTouch = e => {
    e.persist();
    let type = e.type.toLowerCase();

    if (type === "touchstart") {
      lastX = e.touches[0].clientX;
    }

    if (type === "touchmove") {
      currentX = e.touches[0].clientX;
    }

    if (type === "touchend") {
      if (lastX === 0 || currentX === 0 || lastX === currentX) {
        return;
      }
      if (currentX > lastX) {
        this.previous();
        console.log("swife right");
      } else {
        this.next();
        console.log("swife left");
      }
    }
  };

  //Modified render.
  render() {
    const { activeIndex } = this.state;
    const slides = items.map(item => {
      return (
        <CarouselItem
          onExiting={this.onExiting}
          onExited={this.onExited}
          key={item.src}
        >
          <img
            style={{ width: "100%" }}
            src={item.src}
            alt={item.altText}
            onTouchStart={e => this.handleTouch(e)}
            onTouchMove={e => this.handleTouch(e)}
            onTouchEnd={e => this.handleTouch(e)}
            onDragStart={e => this.handleMouse(e)}
            onDragEnd={e => this.handleMouse(e)}
          />
        </CarouselItem>
      );
    });

    return (
      <Carousel
        activeIndex={activeIndex}
        next={this.next}
        previous={this.previous}
        interval={false}
      >
        {slides}

        <CarouselControl
          direction="prev"
          directionText="Previous"
          onClickHandler={this.previous}
        />
        <CarouselControl
          direction="next"
          directionText="Next"
          onClickHandler={this.next}
        />
      </Carousel>
    );
   }
  }

Working demo and the fiddle.

Hope it will help you.

Upvotes: 5

GavinHenderson5
GavinHenderson5

Reputation: 46

As mentioned in another answer you can find a component that has already been built and use that.

However you can implement it yourself using CSS scroll snap and flexbox.

Here's an article which outlines this approach (not in react but still applies).

https://developers.google.com/web/updates/2018/07/css-scroll-snap

Upvotes: 1

ruggierom
ruggierom

Reputation: 109

react-bootstrap has a carousel component

here and there is react-responsive-carousel here

Upvotes: 0

Related Questions