Reputation: 8712
Am developing a chat widget like intercom widget in react js and I want to add carousel cards component, as in facebook messenger.
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
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>
);
}
}
Hope it will help you.
Upvotes: 5
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