1 | React Swipeable
|
2 | =========================
|
3 |
|
4 | React swipe and touch event handler component
|
5 |
|
6 | [![build status](https://img.shields.io/travis/dogfessional/react-swipeable/master.svg?style=flat-square)](https://travis-ci.org/dogfessional/react-swipeable) [![npm version](https://img.shields.io/npm/v/react-swipeable.svg?style=flat-square)](https://www.npmjs.com/package/react-swipeable) [![npm downloads](https://img.shields.io/npm/dm/react-swipeable.svg?style=flat-square)](https://www.npmjs.com/package/react-swipeable) [![gzip size](https://flat.badgen.net/bundlephobia/minzip/react-swipeable)](https://bundlephobia.com/result?p=react-swipeable)
|
7 |
|
8 | [![Edit qq7759m3lq](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/qq7759m3lq?module=%2Fsrc%2FCarousel.js)
|
9 |
|
10 | [Github Pages Demo](https://dogfessional.github.io/react-swipeable/)
|
11 |
|
12 | *Upcoming v5 with `useSwipeable` hook - [PR #114](https://github.com/dogfessional/react-swipeable/pull/114)*. Published as tag `next`.
|
13 |
|
14 | ### Installation
|
15 | ```
|
16 | $ npm install --save react-swipeable
|
17 | ```
|
18 |
|
19 | ### Use
|
20 | ```js
|
21 | import Swipeable from 'react-swipeable'
|
22 |
|
23 | class SwipeComponent extends React.Component {
|
24 |
|
25 | swiping(e, deltaX, deltaY, absX, absY, velocity) {
|
26 | console.log("You're Swiping...", e, deltaX, deltaY, absX, absY, velocity)
|
27 | }
|
28 |
|
29 | swipingLeft(e, absX) {
|
30 | console.log("You're Swiping to the Left...", e, absX)
|
31 | }
|
32 |
|
33 | swiped(e, deltaX, deltaY, isFlick, velocity) {
|
34 | console.log("You Swiped...", e, deltaX, deltaY, isFlick, velocity)
|
35 | }
|
36 |
|
37 | swipedUp(e, deltaY, isFlick) {
|
38 | console.log("You Swiped Up...", e, deltaY, isFlick)
|
39 | }
|
40 |
|
41 | render() {
|
42 | return (
|
43 | <Swipeable
|
44 | onSwiping={this.swiping}
|
45 | onSwipingLeft={this.swipingLeft}
|
46 | onSwiped={this.swiped}
|
47 | onSwipedUp={this.swipedUp} >
|
48 | You can swipe here!
|
49 | </Swipeable>
|
50 | )
|
51 | }
|
52 | }
|
53 | ```
|
54 | react-swipeable(`<Swipeable>`) generates a new React element(`<div>` by default) under the hood and binds touch events to it that are used to fire the `swiping` and `swiped` props.
|
55 |
|
56 | ## Props / Config Options
|
57 |
|
58 | ### Event Props
|
59 |
|
60 | **`onSwiping`**, **`onSwipingUp`**, **`onSwipingRight`**, **`onSwipingDown`**, **`onSwipingLeft`**, are called with the event
|
61 | as well as the absolute delta of where the swipe started and where it's currently at. These constantly fire throughout touch events.
|
62 |
|
63 | **`onSwiping`** in addition to the swipe delta, `onSwiping` also returns the current absolute X and Y position, as well as the current velocity of the swipe. `this.props.onSwiping(e, deltaX, deltaY, absX, absY, velocity)`
|
64 |
|
65 | **`onSwipedUp`**, **`onSwipedRight`**, **`onSwipedDown`**, **`onSwipedLeft`** are called with the event
|
66 | as well as the x distance, + or -, from where the swipe started to where it ended. These only fire at the end of a touch event.
|
67 |
|
68 | **`onSwiped`** is called with the event, the X and Y delta, whether or not the event was a flick, and the current velocity of the swipe. `this.props.onSwiped(e, deltaX, deltaY, isFlick, velocity)`
|
69 |
|
70 | **`onTap`** is triggered when a tap happens, specifically when a swipe/touch moves less than the `delta`. Is called with the onTouchEnd event `this.props.onTap(e)`
|
71 |
|
72 | ### Configuration Props
|
73 |
|
74 | **`flickThreshold`** is a number (float) which determines the max velocity of a swipe before it's considered a flick. The default value is `0.6`.
|
75 |
|
76 | **`delta`** is the amount of px before we start firing events. Also affects how far `onSwipedUp`, `onSwipedRight`, `onSwipedDown`, and `onSwipedLeft` need to be before they fire events. The default value is `10`.
|
77 |
|
78 | **`preventDefaultTouchmoveEvent`** is whether to prevent the browser's [touchmove](https://developer.mozilla.org/en-US/docs/Web/Events/touchmove) event. Sometimes you would like the target to scroll natively. The default value is `false`.
|
79 | * **Notes** `e.preventDefault()` is only called when `preventDefaultTouchmoveEvent` is `true` **and** the user is swiping in a direction that has an associated directional `onSwiping` or `onSwiped` prop.
|
80 | * Example: user is swiping right with `<Swipable onSwipedRight={this.userSwipedRight} preventDefaultTouchmoveEvent={true} >` then `e.preventDefault()` will be called, but if user was swiping left `e.preventDefault()` would **not** be called.
|
81 | * Please experiment with [example](http://dogfessional.github.io/react-swipeable/) to test `preventDefaultTouchmoveEvent`.
|
82 | * `swipeable` versions < `4.2.0` - [Chrome 56 and later, warning with preventDefault](#chrome-56-and-later-warning-with-preventdefault)
|
83 |
|
84 | **`stopPropagation`** automatically calls stopPropagation on all 'swipe' events. The default value is `false`.
|
85 |
|
86 | **`nodeName`** is a string which determines the html element/node that this react component binds its touch events to then returns. The default value is `'div'`.
|
87 |
|
88 | **`trackMouse`** will allow mouse 'swipes' to ***additonally*** be tracked(click, hold, move, let go). See [#51](https://github.com/dogfessional/react-swipeable/issues/51) for more details. The default value is `false`.
|
89 |
|
90 | **`disabled`** will disable `<Swipeable>`: swipes will not be tracked and this stops current active swipes from triggering anymore prop callbacks. The default value is `false`.
|
91 |
|
92 | **`innerRef`** will allow access to the Swipeable's inner dom node element react ref. See [#81](https://github.com/dogfessional/react-swipeable/issues/81) for more details. Example usage `<Swipeable innerRef={(el) => this.swipeableEl = el} >`. Then you'll have access to the dom element that Swipeable uses internally.
|
93 |
|
94 | **`rotationAngle`** will allow to set a rotation angle, e.g. for a four-player game on a tablet, where each player has a 90° turned view. The default value is `0`.
|
95 |
|
96 | **None of the props are required.**
|
97 | ### PropType Definitions
|
98 |
|
99 | #### Event Props:
|
100 | ```
|
101 | onSwiped: PropTypes.func,
|
102 | onSwiping: PropTypes.func,
|
103 | onSwipingUp: PropTypes.func,
|
104 | onSwipingRight: PropTypes.func,
|
105 | onSwipingDown: PropTypes.func,
|
106 | onSwipingLeft: PropTypes.func,
|
107 | onSwipedUp: PropTypes.func,
|
108 | onSwipedRight: PropTypes.func,
|
109 | onSwipedDown: PropTypes.func,
|
110 | onSwipedLeft: PropTypes.func,
|
111 | onTap: PropTypes.func,
|
112 | ```
|
113 | #### Config Props:
|
114 | ```
|
115 | flickThreshold: PropTypes.number, // default: 0.6
|
116 | delta: PropTypes.number, // default: 10
|
117 | preventDefaultTouchmoveEvent: PropTypes.bool, // default: false
|
118 | stopPropagation: PropTypes.bool, // default: false
|
119 | nodeName: PropTypes.string // default: div
|
120 | trackMouse: PropTypes.bool, // default: false
|
121 | disabled: PropTypes.bool, // default: false
|
122 | innerRef: PropTypes.func,
|
123 | rotationAngle: PropTypes.number // default: 0
|
124 | ```
|
125 |
|
126 | ## Development
|
127 |
|
128 | Initial set up, with `node 8+`, run `npm install`.
|
129 |
|
130 | Make changes/updates to the `src/Swipeable.js` file.
|
131 |
|
132 | Before creating a PR please run `npm test` to make sure the tests and lint pass.
|
133 | - Please add tests if PR adds/changes functionality.
|
134 |
|
135 | #### Test changes/updates with the examples
|
136 |
|
137 | Build, run, and test examples locally:
|
138 | `npm run start:examples`
|
139 |
|
140 | After the server starts you can then view the examples page with your changes at `http://localhost:3000`.
|
141 |
|
142 | You can now make updates/changes to `src/Swipeable.js` and webpack will rebuild, then reload the page so you can test your changes!
|
143 |
|
144 | ## Notes
|
145 | ### Chrome 56 and later, warning with preventDefault
|
146 | `swipeable` version `>=4.2.0` should fix this issue. [PR here](https://github.com/dogfessional/react-swipeable/pull/88).
|
147 |
|
148 | The issue still exists in versions `<4.2.0`:
|
149 | - When this library tries to call `e.preventDefault()` in Chrome 56+ a warning is logged:
|
150 | - `Unable to preventDefault inside passive event listener due to target being treated as passive.`
|
151 |
|
152 | This warning is because this [change](https://developers.google.com/web/updates/2017/01/scrolling-intervention) to Chrome 56+ and the way the synthetic events are setup in reactjs.
|
153 |
|
154 | Follow reacts handling of this issue here: [facebook/react#8968](https://github.com/facebook/react/issues/8968)
|
155 |
|
156 | ## License
|
157 |
|
158 | MIT
|