1 | <img src="https://avatars2.githubusercontent.com/u/6412038?v=3&s=200" alt="react logo" title="react" align="right" width="64" height="64" />
|
2 |
|
3 | # react-dnd-touch-backend
|
4 |
|
5 | [![npm version](https://badge.fury.io/js/react-dnd-touch-backend.svg)](http://badge.fury.io/js/react-dnd-touch-backend)
|
6 | [![Dependency Status](https://david-dm.org/yahoo/react-dnd-touch-backend.svg)](https://david-dm.org/yahoo/react-dnd-touch-backend)
|
7 | [![devDependency Status](https://david-dm.org/yahoo/react-dnd-touch-backend/dev-status.svg)](https://david-dm.org/yahoo/react-dnd-touch-backend#info=devDependencies)
|
8 | ![gzip size](http://img.badgesize.io/https://npmcdn.com/react-dnd-touch-backend?compression=gzip)
|
9 |
|
10 | Touch Backend for [react-dnd](https://github.com/gaearon/react-dnd)
|
11 |
|
12 | ## Usage
|
13 | Follow [react-dnd docs](http://gaearon.github.io/react-dnd/) to setup your app. Then swap out `HTML5Backend` for `TouchBackend` as such:
|
14 |
|
15 | ```js
|
16 | import React, { Component } from 'react';
|
17 | import TouchBackend from 'react-dnd-touch-backend';
|
18 | import { DragDropContext } from 'react-dnd';
|
19 |
|
20 | class YourApp extends Component {
|
21 | /* ... */
|
22 | }
|
23 |
|
24 | export default DragDropContext(TouchBackend)(YourApp);
|
25 | ```
|
26 |
|
27 | ### Options
|
28 |
|
29 | You have the following options available to you, which you can pass in like so:
|
30 |
|
31 | ```js
|
32 | DragDropContext(TouchBackend(options))
|
33 | ```
|
34 |
|
35 | Options include:
|
36 |
|
37 | - enableTouchEvents
|
38 | - enableMouseEvents
|
39 | - enableKeyboardEvents
|
40 | - delayTouchStart
|
41 | - delayMouseStart
|
42 | - touchSlop
|
43 | - ignoreContextMenu
|
44 | - scrollAngleRanges
|
45 |
|
46 | ## Tips
|
47 | ### Drag Preview
|
48 | Since native Drag-n-Drop is not currently supported in touch devices. A custom [DragPreview](https://gaearon.github.io/react-dnd/docs-drag-layer.html) is required. Check out the [example](https://github.com/yahoo/react-dnd-touch-backend/blob/master/examples/js/ItemPreview.jsx) for a sample implementation.
|
49 |
|
50 | We might try to build it directly in the Backend itself in the future to compensate for this limitation.
|
51 |
|
52 | ### Mouse events support*
|
53 | You can enable capturing mouse events by configuring your TouchBackend as follows:
|
54 | ```js
|
55 | DragDropContext(TouchBackend({ enableMouseEvents: true }));
|
56 | ```
|
57 | **NOTE*: This is buggy due to the difference in `touchstart/touchend` event propagation compared to `mousedown/mouseup/click`. I highly recommend that you use [react-dnd-html5-backend](https://github.com/gaearon/react-dnd-html5-backend) instead for a more performant native HTML5 drag capability.**
|
58 |
|
59 | ### Other options
|
60 | **touchSlop**
|
61 |
|
62 | * Specifies the pixel distance moved before a drag is signaled.
|
63 | * Default: 0
|
64 | ```js
|
65 | DragDropContext(TouchBackend({ touchSlop: 20 }));
|
66 | ```
|
67 | **ignoreContextMenu**
|
68 |
|
69 | * If true, prevents the `contextmenu` event from canceling a drag.
|
70 | * Default: false
|
71 | ```js
|
72 | DragDropContext(TouchBackend({ ignoreContextMenu: true }));
|
73 | ```
|
74 |
|
75 | **scrollAngleRanges**
|
76 |
|
77 | * Specifies ranges of angles in degrees that drag events should be ignored. This is useful when you want to allow the
|
78 | user to scroll in a particular direction instead of dragging. Degrees move clockwise, 0/360 pointing to the
|
79 | left.
|
80 | * Default: undefined
|
81 | ```js
|
82 | // allow vertical scrolling
|
83 | DragDropContext(TouchBackend({ scrollAngleRanges: [{ start: 30, end: 150 }, { start: 210, end: 330 }] }));
|
84 |
|
85 | // allow horizontal scrolling
|
86 | DragDropContext(TouchBackend({ scrollAngleRanges: [{ start: 300 }, { end: 60 }, { start: 120, end: 240 }] }));
|
87 | ```
|
88 |
|
89 | **getDropTargetElementsAtPoint**
|
90 | * Specify a custom function to find drop target elements at the given point. Useful for improving performance in environments (iOS Safari) where document.elementsFromPoint is not available.
|
91 | * Default: undefined (use document.elementsFromPoint or inline elementsFromPoint "polyfill")
|
92 | ```js
|
93 | const hasNative = document && (document.elementsFromPoint || document.msElementsFromPoint);
|
94 |
|
95 | function getDropTargetElementsAtPoint(x, y, availableDropTargets) {
|
96 | return dropTargets.filter(t => {
|
97 | const rect = t.getBoundingClientRect();
|
98 | return (x >= rect.left && x <= rect.right &&
|
99 | y <= rect.bottom && y >= rect.top);
|
100 | });
|
101 | }
|
102 |
|
103 | // use custom function only if elementsFromPoint is not supported
|
104 | DragDropContext(TouchBackend({
|
105 | getDropTargetElementsAtPoint: !hasNative && getDropTargetElementsAtPoint,
|
106 | }))
|
107 | ```
|
108 |
|
109 | ## Examples
|
110 | The `examples` folder has a sample integration. In order to build it, run:
|
111 | ```bash
|
112 | npm i && npm run dev
|
113 | ```
|
114 | Then navigate to `localhost:7789` or `(IP Address):7789` in your mobile browser to access the example.
|
115 | Code licensed under the MIT license. See LICENSE file for terms.
|