Skip to content

Commit d3b44ee

Browse files
committed
Add deltaX and deltaY to callback, update README and examples.
1 parent bb020a4 commit d3b44ee

File tree

4 files changed

+133
-57
lines changed

4 files changed

+133
-57
lines changed

README.md

Lines changed: 111 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,28 @@
1-
# react-draggable [![Build Status](https://travis-ci.org/mzabriskie/react-draggable.svg?branch=master)](https://travis-ci.org/mzabriskie/react-draggable)
1+
# React-Draggable [![Build Status](https://travis-ci.org/mzabriskie/react-draggable.svg?branch=master)](https://travis-ci.org/mzabriskie/react-draggable)
22

33
A simple component for making elements draggable.
44

55
[View the Changelog](CHANGELOG.md)
66

7-
## Demo
7+
### Demo
88

99
[View Demo](http://mzabriskie.github.io/react-draggable/example/)
1010

1111

12-
## Installing
12+
### Installing
1313

1414
```bash
1515
$ npm install react-draggable
1616
```
1717

1818
If you aren't using browserify/webpack, a
1919
[UMD version of react-draggable](dist/react-draggable.js) is available. It is updated per-release only.
20+
This bundle is also what is loaded when installing from npm. It expects external `React` and `ReactDOM`.
2021

2122
If you want a UMD version of the latest `master` revision, you can generate it yourself from master by cloning this
2223
repository and running `$ make`. This will create umd dist files in the `dist/` folder.
2324

24-
## Details
25+
## Draggable
2526

2627
A `<Draggable>` element wraps an existing element and extends it with new event handlers and styles.
2728
It does not create a wrapper element in the DOM.
@@ -32,41 +33,83 @@ positioning (relative, absolute, or static). Elements can also be moved between
3233
If the item you are dragging already has a CSS Transform applied, it will be overwritten by `<Draggable>`. Use
3334
an intermediate wrapper (`<Draggable><span>...</span></Draggable>`) in this case.
3435

35-
## API
36+
37+
### Draggable API
38+
3639
The `<Draggable/>` component transparently adds draggable to whatever element is supplied as `this.props.children`.
3740
**Note**: Only a single element is allowed or an Error will be thrown.
3841

3942
Props:
4043

41-
**`axis`**: determines which axis the draggable can move. Accepted values:
42-
- `both` allows movement horizontally and vertically (default).
43-
- `x` limits movement to horizontal axis.
44-
- `y` limits movement to vertical axis.
45-
46-
**`handle`**: specifies a selector to be used as the handle that initiates drag.
47-
48-
**`cancel`**: specifies a selector to be used to prevent drag initialization.
49-
50-
**`grid`**: specifies the x and y that dragging should snap to.
51-
52-
**`bounds`**: specifies movement boundaries. Accepted values:
53-
- `parent` restricts movement within the node's offsetParent (nearest node with position relative or absolute), or
54-
- An object with `left, top, right, and bottom` properties. These indicate how far in each direction the draggable can be moved. See [example/index.html](https://github.com/mzabriskie/react-draggable/blob/master/example/index.html) for more on this.
55-
56-
**`start`**: specifies the `x` and `y` that the dragged item should start at. This is generally not necessary to use (you can use absolute or relative positioning of the child directly), but can be helpful for uniformity in your callbacks and with css transforms.
57-
58-
**`moveOnStartChange`**: if true (it defaults false), will move the element if there is a change in `start`. We set this by default to `false` because it can cause unwanted effects if you are not aware of it.
59-
60-
**`zIndex`**: specifies the zIndex to use while dragging.
61-
62-
**`onStart`**: called when dragging starts.
44+
```js
45+
{
46+
// Called when dragging starts. If `false` is returned from this method,
47+
// dragging will cancel.
48+
// These callbacks are called with the arity
49+
// (event: Event,
50+
// {
51+
// position: {left: number, top: number},
52+
// deltaX: number,
53+
// deltaY: number
54+
// }
55+
// )
56+
onStart: Function,
57+
58+
// Called while dragging.
59+
onDrag: Function,
60+
61+
// Called when dragging stops.
62+
onStop: Function,
63+
64+
// Called whenever the user mouses down. Called regardless of handle or
65+
// disabled status.
66+
onMouseDown: Function,
67+
68+
// Specifies the `x` and `y` that the dragged item should start at.
69+
// This is generally not necessary to use (you can use absolute or relative
70+
// positioning of the child directly), but can be helpful for uniformity in
71+
// your callbacks and with css transforms.
72+
start: {x: number, y: number},
73+
74+
// If true, will not call any drag handlers.
75+
disabled: boolean,
76+
77+
// Specifies a selector to be used to prevent drag initialization.
78+
// Example: '.body'
79+
cancel: string,
80+
81+
// Specifies a selector to be used as the handle that initiates drag.
82+
// Example: '.handle'
83+
handle: string,
84+
85+
// Determines which axis the draggable can move. Accepted values:
86+
// - `both` allows movement horizontally and vertically (default).
87+
// - `x` limits movement to horizontal axis.
88+
// - `y` limits movement to vertical axis.
89+
axis: string,
90+
91+
// Specifies movement boundaries. Accepted values:
92+
// - `parent` restricts movement within the node's offsetParent
93+
// (nearest node with position relative or absolute), or
94+
// - An object with `left, top, right, and bottom` properties.
95+
// These indicate how far in each direction the draggable
96+
// can be moved.
97+
bounds: {left: number, top: number, right: number, bottom: number} | string,
98+
99+
// Specifies the x and y that dragging should snap to.
100+
grid: [number, number],
101+
102+
// Specifies the zIndex to use while dragging.
103+
zIndex: number
104+
}
105+
```
63106

64-
**`onDrag`**: called while dragging.
65107

66-
**`onStop`**: called when dragging stops.
108+
Note that sending `className`, `style`, or `transform` as properties will error - set them on the child element
109+
directly.
67110

68111

69-
## Example usage
112+
### Draggable Usage
70113

71114
```js
72115
/** @jsx React.DOM */
@@ -81,12 +124,12 @@ var App = React.createClass({
81124

82125
handleDrag: function (event, ui) {
83126
console.log('Event: ', event);
84-
console.log('Position: ', ui.position);
127+
console.log('Position: ', ui.position);
85128
},
86129

87130
handleStop: function (event, ui) {
88131
console.log('Event: ', event);
89-
console.log('Position: ', ui.position);
132+
console.log('Position: ', ui.position);
90133
},
91134

92135
render: function () {
@@ -113,40 +156,60 @@ var App = React.createClass({
113156
React.renderComponent(<App/>, document.body);
114157
```
115158

116-
## State Problems?
159+
## <DraggableCore>
160+
161+
For users that require more control, a `<DraggableCore>` element is available. This is useful for more programmatic
162+
usage of the element. See [React-Resizable](https://github.com/STRML/react-resizable) and
163+
[React-Grid-Layout](https://github.com/STRML/react-grid-layout) for some examples of this.
117164

118-
`<Draggable>` is a stateful component. This means that it is storing its current drag offsets in its internal state.
119-
This can cause problems with certain integrations. For example, if you change the position of the element manually,
120-
`<Draggable>` can get into trouble as it assumes a translation in the DOM. If you see an element jump around the page
121-
when you click it, this is affecting you.
165+
`<DraggableCore>` is a useful building block for other libraries that simply want to abstract browser-specific
166+
quirks and receive callbacks when a user attempts to move an element. It does not set styles or transforms
167+
on itself.
122168

123-
This is an unfortunate side-effect of dragging, which is inherently stateful.
169+
### DraggableCore API
124170

125-
If you move the element manually, you have two options:
171+
`<DraggableCore>` takes all of the above `<Draggable>` options, with the exception of:
126172

127-
1. Feed the `<Draggable>` an `x` and `y` parameter in the `start` param, and change it as you go while setting
128-
`moveOnStartChange` to `true`, or,
129-
2. When moving the `<Draggable>`, ref the element and
130-
[call `resetState()`](https://github.com/STRML/react-resizable/blob/master/lib/Resizable.jsx#L48).
173+
* `axis`
174+
* `bounds`
175+
* `grid`
176+
* `start`
177+
* `zIndex`
178+
179+
Drag callbacks are called with the following parameters:
180+
181+
```js
182+
{
183+
node: Node
184+
position:
185+
{
186+
// lastX + deltaX === clientX
187+
deltaX: number, deltaY: number,
188+
lastX: number, lastY: number,
189+
clientX: number, clientY: number
190+
}
191+
};
192+
```
131193

194+
----
132195

133-
## Contributing
196+
### Contributing
134197

135198
- Fork the project
136-
- Run the project in development mode: `$ make dev`
199+
- Run the project in development mode: `$ npm run dev`
137200
- Make changes.
138201
- Add appropriate tests
139-
- `$ make test`
202+
- `$ npm test`
140203
- If tests don't pass, make them pass.
141204
- Update README with appropriate docs.
142205
- Commit and PR
143206

144-
## Release checklist
207+
### Release checklist
145208

146209
- Update CHANGELOG
147210
- `make release-patch`, `make release-minor`, or `make-release-major`
148211
- `make publish`
149212

150-
## License
213+
### License
151214

152215
MIT

example/index.html

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -48,24 +48,29 @@
4848
</style>
4949
</head>
5050
<body>
51-
<script src="//cdnjs.cloudflare.com/ajax/libs/react/0.13.3/react-with-addons.min.js"></script>
52-
<script src="//cdnjs.cloudflare.com/ajax/libs/react/0.13.3/JSXTransformer.js"></script>
51+
<script src="//cdnjs.cloudflare.com/ajax/libs/react/0.14.0/react.min.js"></script>
52+
<script src="//cdnjs.cloudflare.com/ajax/libs/react/0.14.0/react-dom.min.js"></script>
53+
<script src="//cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.29/browser.min.js"></script>
5354
<script src="../dist/react-draggable.js"></script>
54-
<script type="text/jsx">
55+
<script type="text/babel">
5556
var Draggable = ReactDraggable;
5657
var App = React.createClass({
5758
getInitialState: function () {
5859
return {
59-
position: {
60+
deltaPosition: {
6061
top: 0, left: 0
6162
},
6263
activeDrags: 0
6364
};
6465
},
6566

6667
handleDrag: function (e, ui) {
68+
var {left, top} = this.state.position;
6769
this.setState({
68-
position: ui.position
70+
deltaPosition: {
71+
left: left + ui.deltaX,
72+
top: top + ui.deltaY,
73+
}
6974
});
7075
},
7176

@@ -79,6 +84,7 @@
7984

8085
render: function () {
8186
var drags = {onStart: this.onStart, onStop: this.onStop};
87+
var {top. left} = this.state.deltaPosition;
8288
return (
8389
<div>
8490
<h1>React Draggable</h1>
@@ -97,8 +103,8 @@ <h1>React Draggable</h1>
97103
</Draggable>
98104
<Draggable onDrag={this.handleDrag} {...drags}>
99105
<div className="box">
100-
<div>I track my position</div>
101-
<div>top: {this.state.position.top.toFixed(0)}, left: {this.state.position.left.toFixed(0)}</div>
106+
<div>I track my deltas</div>
107+
<div>top: {top.toFixed(0)}, left: {left.toFixed(0)}</div>
102108
</div>
103109
</Draggable>
104110
<Draggable handle="strong" {...drags}>

lib/utils/domFns.es6

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,8 @@ export function createUIEvent(draggable, coreEvent) {
155155
position: {
156156
top: coreEvent.position.clientY,
157157
left: coreEvent.position.clientX
158-
}
158+
},
159+
deltaX: coreEvent.position.deltaX,
160+
deltaY: coreEvent.position.deltaY
159161
};
160162
}

webpack.config.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,12 @@ module.exports = {
1717
// React dep should be available as window.React, not window.react
1818
'root': 'React'
1919
},
20-
'react-dom': 'react-dom'
20+
'react-dom': {
21+
'commonjs': 'react-dom',
22+
'commonjs2': 'react-dom',
23+
'amd': 'react-dom',
24+
'root': 'ReactDOM'
25+
}
2126
},
2227
module: {
2328
loaders: [

0 commit comments

Comments
 (0)