react-swipeable-button
Version:
A component to create swipeable button in react
168 lines • 7.87 kB
JavaScript
import React, { Component } from "react";
import "./SwipeableButton.css";
export default class SwipeableButton extends Component {
constructor(props) {
super(props);
this.sliderLeft = 0;
this.isDragging = false;
this.startX = 0;
this.containerWidth = 0;
this.sliderRef = React.createRef();
this.containerRef = React.createRef();
this.onDrag = (e) => {
if (this.state.unlocked || this.props.disabled) {
return;
}
if (this.isDragging) {
const clientX = "touches" in e ? e.touches[0].clientX : e.clientX;
this.sliderLeft = Math.min(Math.max(0, clientX - this.startX), this.containerWidth);
this.updateSliderStyle();
}
};
this.updateSliderStyle = () => {
if (this.state.unlocked)
return;
if (this.sliderRef.current) {
this.sliderRef.current.style.left = `${this.sliderLeft + 50}px`;
}
};
this.stopDrag = () => {
if (this.state.unlocked)
return;
if (this.isDragging) {
this.isDragging = false;
if (this.sliderLeft > this.containerWidth * 0.9) {
this.sliderLeft = this.containerWidth;
this.onSwiped();
}
else {
this.sliderLeft = 0;
if (this.props.onFailure) {
this.props.onFailure();
}
}
this.updateSliderStyle();
}
};
this.startDrag = (e) => {
if (this.state.unlocked)
return;
this.isDragging = true;
this.startX = "touches" in e ? e.touches[0].clientX : e.clientX;
};
this.onSwiped = () => {
if (this.containerRef.current) {
this.containerRef.current.style.width = `${this.containerRef.current.clientWidth}px`;
}
this.setState({
unlocked: true,
}, () => {
if (this.props.onSuccess) {
this.props.onSuccess();
}
});
};
this.getText = () => {
return this.state.unlocked
? this.props.text_unlocked || "UNLOCKED!"
: this.props.text || "SWIPE";
};
this.buttonReset = () => {
if (!this.state.unlocked)
return;
this.setState({ unlocked: false }, () => {
this.sliderLeft = 0;
this.updateSliderStyle();
});
};
this.buttonComplete = () => {
if (this.state.unlocked)
return;
this.sliderLeft = this.containerWidth;
this.updateSliderStyle();
this.onSwiped();
};
this.state = {
unlocked: false,
};
}
componentDidMount() {
if (this.containerRef.current) {
const containerWidth = () => {
if (this.containerRef.current) {
this.containerWidth = this.containerRef.current.clientWidth - 50;
}
};
containerWidth();
// NOTE: this setTimeout is sometimes necessary to run in Storybook
setTimeout(() => {
containerWidth();
}, 250);
}
document.addEventListener("mousemove", this.onDrag);
document.addEventListener("mouseup", this.stopDrag);
document.addEventListener("touchmove", this.onDrag);
document.addEventListener("touchend", this.stopDrag);
}
componentWillUnmount() {
document.removeEventListener("mousemove", this.onDrag);
document.removeEventListener("mouseup", this.stopDrag);
document.removeEventListener("touchmove", this.onDrag);
document.removeEventListener("touchend", this.stopDrag);
}
render() {
const { width = 300, height = 50, circle = true, disabled = false, noAnimate = false, autoWidth = false, name = "react-swipeable-button", color, sliderColor, background_color = "#eee", borderRadius = 30, sliderTextColor = "#fff", sliderIconColor = "#fff", textColor = "#000", buttonChildren, buttonChildrenUnlocked, } = this.props;
const finalSliderColor = sliderColor || color || "#16362d";
// Log a warning if the deprecated color prop is used
if (color && !sliderColor) {
console.warn("Deprecation Warning: The 'color' prop is deprecated and will be removed in future versions. Please use 'sliderColor' instead.");
}
return (React.createElement("div", { key: name, className: `ReactSwipeButton ${disabled ? "rsbContainerDisabled" : ""}`, style: {
width: autoWidth ? "100%" : `${width}px`,
height: `${height}px`,
} },
React.createElement("div", { className: `rsbContainer ${this.state.unlocked ? "rsbContainerUnlocked" : ""} `, ref: this.containerRef, style: {
borderRadius: circle ? "50px" : "5px",
backgroundColor: background_color,
} },
!noAnimate && !disabled && !this.state.unlocked && (React.createElement("div", { className: "sliderShimmer" })),
React.createElement("div", { className: `rsbcSlider`, ref: this.sliderRef, onMouseDown: this.startDrag, style: {
background: finalSliderColor,
borderRadius: circle ? `${borderRadius}px` : "0px",
}, onTouchStart: this.startDrag },
buttonChildren ? (React.createElement("div", { style: {
display: "flex",
alignItems: "center",
justifyContent: "center",
height: "100%",
} }, this.state.unlocked && buttonChildrenUnlocked
? buttonChildrenUnlocked
: buttonChildren)) : (React.createElement("span", { className: `rsbcSliderText ${noAnimate || this.state.unlocked || disabled
? ""
: "textAnimate"}`, style: { color: sliderTextColor } }, this.getText())),
React.createElement("span", { className: "rsbcSliderArrow", style: {
border: `2px solid ${sliderIconColor}`,
borderLeftColor: "transparent",
borderBottomColor: "transparent",
transformOrigin: "center",
} }),
React.createElement("span", { className: "rsbcSliderCircle", style: { background: finalSliderColor } })),
buttonChildren ? (React.createElement("div", { style: {
display: "flex",
alignItems: "center",
justifyContent: "center",
height: "100%",
} }, this.state.unlocked && buttonChildrenUnlocked
? buttonChildrenUnlocked
: buttonChildren)) : (React.createElement("div", { className: `rsbcText ${noAnimate || this.state.unlocked || disabled
? ""
: "textAnimate"}`, style: {
color: textColor,
width: "100%",
"--shimmer-color": textColor === "#fff" || textColor === "white"
? "rgba(128, 128, 128, 0.8)"
: "rgba(255, 255, 255, 1)",
} }, this.getText())))));
}
}
//# sourceMappingURL=SwipeableButton.js.map