Overview of react-swipeable
mainreact-swipeable is a React hook designed to handle swipe events. It provides a simple way to detect swipe gestures (like swipe left, swipe right, etc.) on elements within a React application.repository·main·Indexed 24 days ago
https://github.com/formidablelabs/react-swipeableA lightweight React hook for detecting touch and mouse swipe gestures. It provides directional handlers (onSwipedLeft, onSwipedRight, onSwipedUp, onSwipedDown), lifecycle handlers (onSwipeStart, onSwiping, onTap), and configurable options for swipe distance (delta), duration, and browser scroll prevention. Compatible with react >= 16.8.3.
react-swipeable is a React hook designed to handle swipe events. It provides a simple way to detect swipe gestures (like swipe left, swipe right, etc.) on elements within a React application.To implement swipe functionality in your React application, follow these three steps:
useSwipeable hook from react-swipeable.useSwipeable (e.g., defining onSwiped).handlers object onto the HTML element you want to track swipes on.This binds the necessary touch and mouse events to that specific element.
import { useSwipeable } from 'react-swipeable';
const handlers = useSwipeable({
onSwiped: (eventData) => console.log("User Swiped!", eventData),
...config,
});
return <div {...handlers}> You can swipe here </div>;To run the example applications on your local machine, navigate to the examples directory and execute the following commands using yarn:
yarnyarn startThe examples can also be viewed online at http://stack.formidable.com/react-swipeable/ or explored via CodeSandbox.
yarn && yarn startUse the preventScrollOnSwipe prop to stop the browser from scrolling while a user is swiping.
When preventScrollOnSwipe is true, Swipeable calls e.preventDefault() on the touchmove event. This only occurs if:
preventScrollOnSwipe is true.trackTouch is true.onSwiping or onSwiped handler/prop.Important Notes:
preventScrollOnSwipe supersedes touchEventOptions.passive for the touchmove listener. When true, the touchmove listener is set to { passive: false } to allow preventDefault(). Other listeners remain { passive: true }.touch-action property on the container instead of using this prop.To generate the static version of the documentation site, run yarn build. This command produces static content in the build directory, which can then be hosted on any static content hosting service.
$ yarn buildTo run the documentation site for development, install the dependencies using yarn and then start the local development server with yarn start. The development server supports live reloading, so most changes will be reflected in the browser immediately without a restart.
$ yarn
$ yarn startTo attach swipe functionality to the entire document instead of a specific DOM element, you can manually pass the document object to the ref returned by useSwipeable.
Important: You must clean up the event listeners by calling ref({}) in the useEffect cleanup function to prevent memory leaks or unexpected behavior.
const { ref } = useSwipeable({
...
}) as { ref: RefCallback<Document> };
useEffect(() => {
ref(document);
// Clean up swipeable event listeners
return () => ref({});
});If you need to use both the ref provided by useSwipeable (to attach swipe handlers) and your own ref (to access the DOM element), you can use a ref passthrough function. Instead of passing a useRef object directly to the ref prop, pass a function that calls handlers.ref(el) and then assigns the element to your own ref.
const MyComponent = () => {
const handlers = useSwipeable({ onSwiped: () => console.log('swiped') })
// setup ref for your usage
const myRef = React.useRef();
const refPassthrough = (el) => {
// call useSwipeable ref prop with el
handlers.ref(el);
// set myRef el so you can access it yourself
myRef.current = el;
}
return (<div {...handlers} ref={refPassthrough} />)
}To prevent the page (or body) from scrolling while a user is swiping an element, you can use the CSS touch-action property. This is often a simpler and more performant alternative to using the preventScrollOnSwipe option in react-swipeable (which relies on event.preventDefault() during onTouchMove).
Refer to the MDN documentation for touch-action to choose the appropriate CSS value for your specific interaction model.
When upgrading from version 6 to version 7, the primary breaking change involves the renaming of the property used to control scroll prevention during swipe gestures.
Replace preventDefaultTouchmoveEvent with preventScrollOnSwipe. This prop provides the same functionality but with a more explicit name. In v7, this prop specifically controls the passive event listener option for touchmove events to ensure correct behavior.
const handlers = useSwipeable({
- preventDefaultTouchmoveEvent: true,
+ preventScrollOnSwipe: true,
});You can customize the behavior of the swipe detection using configuration props.
delta: The minimum distance (px) required before a swipe starts. This can be a number or an object to specify different thresholds for each direction (left, right, up, down). Unspecified directions default to 10.swipeDuration: The maximum allowable duration (ms) for a swipe. If a swipe lasts longer than this value, it will not be considered a swipe, no callbacks will trigger, and tracking will stop. Defaults to Infinity.trackTouch: Whether to track touch input (defaults to true).trackMouse: Whether to track mouse input (defaults to false).rotationAngle: Sets a rotation angle for swipe detection.preventScrollOnSwipe: Prevents browser scrolling during a swipe (defaults to false).touchEventOptions: Options for touch listeners (e.g., { passive: true }). Note that preventScrollOnSwipe supersedes this for the touchmove event.{
delta: 10, // min distance(px) before a swipe starts. *See Notes*
preventScrollOnSwipe: false, // prevents scroll during swipe (*See Details*)
trackTouch: true, // track touch input
trackMouse: false, // track mouse input
rotationAngle: 0, // set a rotation angle
swipeDuration: Infinity, // allowable duration of a swipe (ms). *See Notes*
touchEventOptions: { passive: true }, // options for touch listeners (*See Details*)
}You can build a carousel by combining useSwipeable with a state management pattern (like useReducer) to handle directional movement.
Key implementation details:
onSwipedLeft and onSwipedRight within the useSwipeable configuration to trigger movement functions.swipeDuration (e.g., 500) to define the maximum duration of a swipe to be recognized.preventScrollOnSwipe: true to ensure the swipe gesture doesn't trigger page scrolling.trackMouse: true if you want the swipe gestures to work with a mouse as well as touch.handlers returned by useSwipeable onto the wrapper element of your component.const Carousel: FunctionComponent<{children: ReactNode}> = (props) => {
const numItems = React.Children.count(props.children);
const [state, dispatch] = React.useReducer(reducer, getInitialState(numItems));
const slide = (dir: Direction) => {
dispatch({ type: dir, numItems });
setTimeout(() => {
dispatch({ type: 'stopSliding' });
}, 50);
};
const handlers = useSwipeable({
onSwipedLeft: () => slide(NEXT),
onSwipedRight: () => slide(PREV),
swipeDuration: 500,
preventScrollOnSwipe: true,
trackMouse: true
});
return (
<div {...handlers}>
<Wrapper>
<CarouselContainer dir={state.dir} sliding={state.sliding}>
{React.Children.map(props.children, (child, index) => (
<CarouselSlot
order={getOrder(index, state.pos, numItems)}
>
{child}
</CarouselSlot>
))}
</CarouselContainer>
</Wrapper>
<SlideButtonContainer>
<SlideButton onClick={() => slide(PREV)} float="left">
Prev
</SlideButton>
<SlideButton onClick={() => slide(NEXT)} float="right">
Next
</SlideButton>
</SlideButtonContainer>
</div>
);
};