react-dnd / react-dnd Goto Github PK
View Code? Open in Web Editor NEWDrag and Drop for React
Home Page: http://react-dnd.github.io/react-dnd
License: MIT License
Drag and Drop for React
Home Page: http://react-dnd.github.io/react-dnd
License: MIT License
As we move towards implementing alternative backends, we need to make NativeDragDropSupport
clean up after itself when last draggable/droppable component is unmounted. Something like setup()
and teardown()
.
In the example below acceptDrop is not called:
configureDragDrop(registerType) {
registerType(DndTypes.ITEM, {
dragSource: {
beginDrag() {
return {
item: {
id: this.props.id
}
};
}
},
dropTarget: {
over(item) {
this.props.moveCard(item.id, this.props.id);
return true;
},
acceptDrop() {
this.props.cardMoved();
}
}
});
},
I propose we make configureDragDrop
static, and pass current component
as the first argument to each method. This change is a stepping stone to fix endDrag
not firing on unmounted component (#38, we'll pass null
as component
) and also a stepping stone to allow “resurfacing” drag sources (#53, we'll pass another component as component
).
I'd like this change to be implemented in a backward-compatible way with a deprecation warning. We will make it a breaking change in 1.0 with #48.
configureDragDrop
and pass component
as the first argument to all methodsconfigureDragDrop
definitions (without component
parameter)1.0
branch.Any comments or volunteers?
If I drop a file too fast, sometimes it isn't handled by react-dnd and instead browser opens a local file. We should probably disable default file drop action completely since I can't think of a single reason where it would be in the interest of the user.
I have a short experience with compiled javascript and I am using browserify to compile and concat my scripts.
When I include var DragDropMixin = require('react-dnd');
, I have the following error in the browser
Uncaught ReferenceError: Reflect is not defined main.js:3974(anonymous function) main.js:3974./DOMPropertyOperations main.js:3979s main.js:1(anonymous function) main.js:1./React main.js:7296s main.js:1(anonymous function) main.js:1./ReactLink main.js:3626s main.js:1(anonymous function) main.js:1(anonymous function) main.js:9145./LinkedStateMixin main.js:9173s main.js:1(anonymous function) main.js:1./lib/ReactWithAddons main.js:1830s main.js:1(anonymous function) main.js:1./components/RealManager main.js:11952s main.js:1e main.js:1(anonymous function) main.js:1
My gulfile looks like this https://gist.github.com/anonymous/5673caf90e5a9977812b
gulp.task('browserify', function () {
gulp.src('src/js/main.js')
.pipe(browserify({transform: browserifyTransform}))
.pipe(concat('main.js'))
.pipe(gulp.dest('dist/js'));
});
Any idea?
https://github.com/gaearon/react-dnd#production-usage
Feel free to send a PR adding your company and describing your user case.
Without this we may have performance regressions from being unable to use the PureRenderMixin correctly
It would be nice to be able to handle drag-n-drop of files with the same API.
If consumer code fails inside drag-n-drop hooks (enter
, acceptDrop
, etc), we should rethrow, but it would be nice to wrap these calls into try-finally
to restore state when it makes sense. For example, an error inside acceptDrop
shouldn't cause mixin to go into “waiting for drop” mode forever.
I'm using react-dnd for a kanban board app (trello like), and when moving a card to another list (thus unmounting source component during drag), the endDrag
function is not called, as the listeners for DragDropStore
are removed on unmount.
As a workaround, I've added a _lastDraggedItem
and getLastDraggedItem
to DragDropStore
, and subscribed to DragDropStore
on parent component, handling the endDrag there. As we clear the variables in DragDropStore
before firing the DRAG_END
event, I couldn't find any other way to get dragged item.
The reason I'm not using DROP
event is, it's not fired when the item is dropped outside of browser window, only DRAG_END
is fired.
It works but it's messy, breaking the beginDrag
& endDrag
symmetry.
Are there any other ways to trigger a function on endDrag
, with access to dragged item?
Or if is this a valid usecase for others, should we add my workaround to the repo?
The dependency lodash-node has been deprecated.
Would be awesome to support drag handles. Sometimes you just want to make a small area on an element draggable but drag the whole element with it.
First of all, thanks for the great work.
I've just used it to create a d&d area for files to be uploaded, and works just file. I have
configureDragDrop: function(register) {
register(NativeDragItemTypes.FILE, {
dropTarget: {
enter: function(component){
...
},
leave: function(component){
...
},
acceptDrop: function(component, item) {
component.addFiles(item.files)
}
}
})
}
I also have a file input and keep the file input & drag-drop area in sync. So users can upload either via file input or via drag-drop.
My problem is that with the file input, I can filter files by specifing the accept
attribute. Is there a way to specify the accept attribute for the droptarget?
(I know I could filter them in the acceptDrop, but that is not idiomatic)
Thanks.
If I load the demo on my phone I can't move anything.
Are touch events supported? If not do you think it would be possible to use this library with some existing scripts that map touch events to mouse events?
It'd be killer if there was a touch backend that would be switched-in automatically for touch devices.
Hi
I see that there was a kanban example in progress. When do you think release it ?
Do you have a working progress example so i could help you finish it ?
Thx.
I noticed that if I remove drag source node while drag operation is in progress, it never finishes. The reason for this is dragend
not firing on removed elements.
We should perhaps add top-level window
drop
handler around here to check if drag source node was removed from DOM. In this case, we should somehow invoke pending handleDragEnd
because the component might still be mounted (even though one of inner nodes was removed).
We need to think if we should invoke handleDragEnd
if the component itself is unmounted by the time it happens. Probably not, but this would break beginDrag
/endDrag
symmetry. Another option is to invoke endDrag
in componentWillUnmount
with didDrop=false
if there is a pending drag operation by the time component is unmounted.
DragLayerMixin
x
and y
, figure out what we should keep in DragLayer
stateI intend to keep using some ES6 features in this code.
If you're using JSX, you can specify harmony: true
(jsx?harmony
in Webpack) in your JSX build step to get them for free. If not, I don't mind accepting a PR that adds a build step before publishing to NPM; however I won't accept a PR downgrading to ES5.
With nested dropzones, we need to make it possible for child dropzone to “take over”, so that parent becomes inactive when item is dragged over child.
While it's possible to do e.stopPropagation()
inside over
/ leave
/ enter
/ acceptDrop
, it interferes with how react-dnd works around brower hacks because events never reach window
in this case.
I'm not sure how to handle this yet.
Thanks for awesome lib.
On Chrome, if I remove the item from DOM after dragging starts, and drop the item outside of the browser window, drop event is not triggered. (I'm checking it on DragDropStore).
No problems on FF, when mouse is moved out of the browser window, drop event triggers immediately.
As a workaround, I've removed the isFirefox() check from the _lastDragSourceCheckTimeout
in NativeDragDropSupport.js, but haven't tested much yet if it breaks normal functionality in Chrome.
Looked around the source code a little bit for another fix, but couldn't come up with any.
If you think some parts of API have confusing naming, please suggest alternatives here.
I'd start with
registerType
-> register
dropState.isHovering
-> dropState.isOver
Anything else?
I noticed that on IE the hack with setting a transparent pixel image as dragPreview
does not work for some reason.
We need to
getEmptyImage
.Maybe, adding an empty DOM node to the document and using it as dragPreview
will work. I'm not sure.
It any case, I suggest we do this when dragPreview
is explicitly set to be null
rather than undefined
. We'll just do whatever we need to hide it in all browsers including IE.
Привет. Hi.
I'm using this component http://facebook.github.io/fixed-data-table/ and render cell into their column which have DragDropMixin, it almost working, however positioning of dragPreview begins with first element in table(even header). I'm wonder, is it something we can control? Or is it internals of fixed-data-table?
Can you provide a jsfiddle of Draggable ?
We need to bring code in backend-mousemove
branch up to date with changes from 1.0
branch. Currently they're diverged. This involves some manual merging between DragDropMixin
(from 1.0
) and createDragDropMixin
(from backend-mousemove
).
After this is done, I suggest we extract a separate branch that contains parts of backend-mousemove
not related to MouseMove/TouchMove backends. This should include: potential support for these backends via createDragDropMixin(backend)
and backends\HTML5
, some new helpers in utils
.
This should also include DragFeedbackMixin
(let's rename it to DragLayerMixin
) and drag-around-experimental
example, but without MouseDragDropMixin
—let it use HTML5 backend instead (as it actually did before). This would be our only new example in this branch.
The goal is to have custom rendering (via DragFeedbackMixin
) and backend refactoring for 1.0.
When this is done, we will need to fix this TODO and merge the result into 1.0.
Next steps would be:
getKey
(#64) and proper resurfacing support;For example, when dragging a file to the last bin in this example: http://gaearon.github.io/react-dnd/#/dustbin-interesting
0.8.0 adds DragLayerMixin
which allows you to implement custom drawing layer:
http://gaearon.github.io/react-dnd/#/drag-around-custom
https://github.com/gaearon/react-dnd/tree/master/examples/_drag-around-custom
If you turn on snapping, you'll notice transition is abrupt. It would be nice to let DragLayerMixin
consumer delay endDrag
until it performs some animation.
I don't want to think hard about this until 1.0 is out, but I'll keep an issue for posterity.
https://monosnap.com/image/G54T5ogrqiSHPjB1P4mcwaJ8UauFlS
Hello! I think that I found trouble in this.getDropState(TYPE).isHovering. As you can see on the screenshot above when there is some drop targets in hierarchy they are ALL has isHovering state.
But I think that hovering state shouldn't bubble from child to parent (on screenshot red arrows show where hovering is wrong).
Thank you!
With dragPreview: Image
, Safari 8 seems to calculate drag offsets differently in my Yosemite beta. Need to update to the released Yosemite and verify it behaves differently, add a check for Safari 8 and apply whatever changes it needs.
There is a common pattern that is hard to implement with native drag and drop: dragging multiple elements. While selection mechanics might vary from app to app (cmd+clicking, checkboxes, predefined groups), but it would be nice to at least make it possible to support this scenario.
Because multiple dragged items may not be siblings in DOM and setDragImage(element, x, y)
is pretty much insane and hasn't gotten any better, we won't burden ourselves with trying to render several elements in drag preview at once.
How can we help implement this scenario, if we can't show a "multiple" drag preview?
In a way, this scenario is already possible: consumers can manually keep track of selected elements, set dragPreview
to some kind of generic placeholder Image
and react appropriately to the dropping of (as far as business logic is concerned) several elements.
However there is currently no supported way for one element to know that it's part of a group that's being dragged. From react-dnd's point of view, if we drag something, this component gets getDragState(type).isDragging = true
, but other components don't. From your app point of view, if you support multiple selection, you want all logically "selected" items to be aware that they're being dragged, even if only one of them is being actually "DOM-dragged".
What we need is a way for components to tell react-dnd that, “hey, although onDragStart
was received by another component, I want to pretend that I'm being dragged too, and have my getDragState(type)
mirror dragged component's getDragState(type)
, and have my endDrag(didDrop)
called too so I could do my stuff”.
How would components opt into that?
If I attach a drag handle to an element, that is a drag source for its parent, it would be nice that when onDrag is invoked, that it clones the image of the parent...and not just the drag handle.
We want to support nested drop target, but make it easy for parent targets to opt out of events when children are active. We have several requirements:
e
argument for e.stopPropagation
and the likes. Ideally, we'll deprecate e
and stop passing it in 1.0.over
(e.g. to scroll the view) even if it doesn't handle drag. For this reason, each drop target should be able to decide on its own whether it wants to react to drop and whether it needs to hover.We already note nesting in acceptDrop
: if isHandled
is true
, this means some child has already handled drop before us (and parent may decide not to do anything in this case). We need a similar API for enter
/over
/leave
as well as their this.getDropState(type).isHovering
counterpart.
#85 starts this work by adding a nested dustbin example. We want to find a good API to make it work.
There's an attempt at adding API for this in #76 but it's currently too noisy. @itrelease, can you please write down the API you're proposing there? Or else you can reimplement it on top of #85 so we can see where you're heading.
This issue supersedes #75.
Using react-dnd with React 0.12.0 is giving me a few warnings due to changes to React in the most recent version, namely:
react/lib/copyProperties has been deprecated and will be removed in the next version of React. All uses can be replaced with Object.assign(obj, a, b, ...) or _.extend(obj, a, b, ...).
and
react/lib/merge has been deprecated and will be removed in the next version of React. All uses can be replaced with Object.assign({}, a, b) or _.extend({}, a, b).
You can supply effectsAllowed
in drag source's beginDrag()
but there is no way to specify drop target's dropEffect
other than via native browser event:
dropTarget: {
over(item, e) {
if (e.target === e.currentTarget) {
e.dataTransfer.dropEffect = 'move';
}
},
We should probably abstract that away by adding an optional getDropEffect(allowedEffects)
to drop target's contract. When it is implemented, it will be used to set dropEffect
in dragenter
and dragover
events. Additionally, when drop target is inactive, we should specify none
as dropEffect
ourselves. Mixin should compare e.target === e.currentTarget
before setting e.dataTransfer.dropEffect
inside the mixin so parent drop zones don't override children when propagating dragenter
and dragover
.
I want to drag elements to o container, but after I drop them on target they will go back.
The original item stays on his place, but dragging moves a ghost of it.
When we drop drag preview outside any drop zone, WebKit performs a “return” animation to where the DOM node is.
However if we have moved DOM node itself (common pattern when re-ordering items), and later drop item outside of any drop zone, WebKit still animates the drag preview—but to its old position. In other words, WebKit doesn't realize source DOM node has moved.
When using dragPreview: Image
, drag offsets are incorrect.
Firefox 33, OS X Mavericks, Retina.
I'll add a usage overview in README but it would be nice to make a Github page with a sample app.
If anyone's interested, let me know.
We should gather all valid use cases for it and allow to do the same via context
passed to configureDragDrop
. For example, you can already get the delta between start and current drag positions by calling getCurrentOffsetDelta
.
This will be a breaking change in 1.0. We want to do this because doing something like e.preventPropagation
was always bad (instead we need #87), and we want to hide internals better so people don't rely on particular drag and drop implementation, and adding touch support in future is easier.
While an item is being dragged, simultaneously using the scroll wheel does not scroll the page.
I am writing a custom drag and drop sortable. I got the problem which example of sortable solved. But I want to self write my own lib with small function.
My problem is how to style the drag source and drop target with different style. (In this case, the drop target maybe blank and drag source is our component). I read code and see the lib use dataTransfer and setDragImage is dragpreview. But I don't know how to get the dragpreview.
Any body suggest me a simple solution?
Greetings. I have a use case in ES5 (not surprisingly), so it is great to have the mixing in ES5 as provided. However, I find it hard to parse ES6 in my head at the same time that I try to understand how the mixing works in the examples...
Is there any change you’ll eventually add ES5 examples :)
http://gaearon.github.io/react-dnd/#/dustbin-interesting
... need to initialize React for touch?
I tried copying for code from the 'simple' example but have not been able to get it to work. I get a continuous (when the dragged item is hovering over the drop target)
undefined is not a function
error in isAnyDropTargetActive
Strangely, when i put a break point on that function and step through, i don't get that error but instead get another error - can't read property 0 of null
in getDropEffect function. Looks like it's trying to get [0] index of null (_effectsAllowed)
I tried going back to version 0.6.0, but the same problem persists.
Screenshot of the stack trace -
After v1.0 and #48, we will probably want to make our testing story better. Taking cues react-router, we will implement TestBackend
, a special drag-and-drop backend that allows you to simulate and test drag and drop without actually firing any browser events.
I fixed a few IE crashes in 0.6.2 but for some reason sortable example does not appear to be working in IE11 (items are dragged but not moved). It's either an issue with the example (lacking or differently named MouseEvent
properties?), or with some part of library—worth investigating.
Hi, do you have a sample code for testing a drag and drop interaction?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.