|
1 | 1 | import {default as React, PropTypes} from 'react'; |
2 | 2 | import {matchesSelector, createCoreEvent, addEvent, removeEvent, addUserSelectStyles, |
3 | 3 | removeUserSelectStyles, styleHacks} from './utils/domFns'; |
4 | | -import {getControlPosition} from './utils/positionFns'; |
| 4 | +import {getControlPosition, snapToGrid} from './utils/positionFns'; |
5 | 5 | import {dontSetMe} from './utils/shims'; |
6 | 6 | import log from './utils/log'; |
7 | 7 |
|
@@ -69,6 +69,25 @@ export default class DraggableCore extends React.Component { |
69 | 69 | */ |
70 | 70 | enableUserSelectHack: PropTypes.bool, |
71 | 71 |
|
| 72 | + /** |
| 73 | + * `grid` specifies the x and y that dragging should snap to. |
| 74 | + * |
| 75 | + * Example: |
| 76 | + * |
| 77 | + * ```jsx |
| 78 | + * let App = React.createClass({ |
| 79 | + * render: function () { |
| 80 | + * return ( |
| 81 | + * <Draggable grid={[25, 25]}> |
| 82 | + * <div>I snap to a 25 x 25 grid</div> |
| 83 | + * </Draggable> |
| 84 | + * ); |
| 85 | + * } |
| 86 | + * }); |
| 87 | + * ``` |
| 88 | + */ |
| 89 | + grid: PropTypes.arrayOf(PropTypes.number), |
| 90 | + |
72 | 91 | /** |
73 | 92 | * `handle` specifies a selector to be used as the handle that initiates drag. |
74 | 93 | * |
@@ -195,6 +214,7 @@ export default class DraggableCore extends React.Component { |
195 | 214 | disabled: false, |
196 | 215 | enableUserSelectHack: true, |
197 | 216 | handle: null, |
| 217 | + grid: null, |
198 | 218 | transform: null, |
199 | 219 | onStart: function(){}, |
200 | 220 | onDrag: function(){}, |
@@ -285,10 +305,19 @@ export default class DraggableCore extends React.Component { |
285 | 305 |
|
286 | 306 | let {clientX, clientY} = getControlPosition(e); |
287 | 307 |
|
| 308 | + // Snap to grid if prop has been provided |
| 309 | + if (Array.isArray(this.props.grid)) { |
| 310 | + let deltaX = clientX - this.state.lastX, deltaY = clientY - this.state.lastY; |
| 311 | + [deltaX, deltaY] = snapToGrid(this.props.grid, deltaX, deltaY); |
| 312 | + if (!deltaX && !deltaY) return; // skip useless drag |
| 313 | + clientX = this.state.lastX + deltaX, clientY = this.state.lastY + deltaY; |
| 314 | + } |
| 315 | + |
288 | 316 | let coreEvent = createCoreEvent(this, clientX, clientY); |
289 | 317 |
|
290 | 318 | log('DraggableCore: handleDrag: %j', coreEvent.position); |
291 | 319 |
|
| 320 | + |
292 | 321 | // Call event handler. If it returns explicit false, trigger end. |
293 | 322 | let shouldUpdate = this.props.onDrag(e, coreEvent); |
294 | 323 | if (shouldUpdate === false) { |
|
0 commit comments