React-dnd: No auto-scroll on drag

Created on 11 Oct 2016  ·  19Comments  ·  Source: react-dnd/react-dnd

To reproduce :
Please open example page on safari or firefox ( maybe IE ) : https://gaearon.github.io/react-dnd/examples-sortable-simple.html
And resize browser keep some of elements of list outside screen, then try to drag, page should scroll during drag but not. ( In chrome works correctly )
This issue is open in Firefox.
You may want to check releated stack overflow question.
http://stackoverflow.com/questions/16822920/scroll-while-using-html5-drag-and-drop

As a solution :
Please checkout https://github.com/martindrapeau/jQueryDndPageScroll/blob/master/jquery.dnd_page_scroll.js

Also working example
https://jsfiddle.net/0vv7fs63/2/

I'm not suggesting to use jquery plugin but checking source code.
Simply adding two divs ( top and bottom of the page ) and listening drag over/enter events, and scrolling accordingly is the solution.

wontfix

Most helpful comment

Looks like react-dnd-scrollzone no longer works with the latest react-dnd. IMO drag scrolling should be part of the react-dnd core.

All 19 comments

there's this solution to react-dnd: https://github.com/azuqua/react-dnd-scrollzone
maybe this issue could be closed now @darthtrevino

Please Sortable developers, provide some solution to this.

how to use it can you look for me ? @nossila

@AsceticBoy I can't do a better job than it's README, tons of examples there

I did my own implementation of this. Basically added the listcontainer as a Drop Target.

Used: findDOMNode(component).getBoundingClientRect()
to know when I was at either side of the listcontainer

then: listContainerDOMNode.scrollLeft += someValue
to scroll the list, which scrolls the listcontainer.

It's a good start but the problem is that if the user holds the pointer still no hover event is triggered and so the scrolling stops.

Has anyone solved this, scrolling the listcontainer when the pointer is still?

@nossila ty! react-dnd-scrollzone works as charm :)

I know this is an old thread but still open...

Has anyone successfully setup react-dnd-scrollzone with WindowScroller from react-virtualized in tandem. And if so, could you share the implementation.

I'm using a combination of WindowScroller, AutoSizer and List; and have not been able to get scrollzone working properly.

I realized that my problem is that I'm using a custom scrollElement with WindowScroller, where react-dnd-scrollzone sets it container as the element it wraps. I'm forking it to add a custom scroll element prop.

Looks like react-dnd-scrollzone no longer works with the latest react-dnd. IMO drag scrolling should be part of the react-dnd core.

Below is my solution:

const autoScrollInSafari = (step = 4) => (fn) => {
  const inSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);

  if (inSafari) {
    return function (p, m, c) {
      const scrollDOM = document.querySelector('.your-scroll-dom-class');
      if (scrollDOM) {
        const cursor = m.getClientOffset();
        const rect = scrollDOM.getBoundingClientRect();
        if (cursor.y - rect.top < 50) scrollDOM.scrollTop -= step;
        if (rect.bottom - cursor.y < 50) scrollDOM.scrollTop += step;
        if (cursor.x - rect.left < 50) scrollDOM.scrollLeft -= step;
        if (rect.right - cursor.x < 50) scrollDOM.scrollLeft += step;
      }
      fn.apply(this, [p, m, c]);
    };
  }

  return fn;
};

const myDropSpec = {
  drop() {
    // your drop callback
  },
  hover: autoScrollInSafari((props, monitor, component) => {
    // your hover callback
  }),
}

Hope this help. :smile:

An updated fork of scrollzone (https://github.com/frontend-collective/frontend-collective-react-dnd-scrollzone) works with more modern versions of react-dnd up to and including 7.0.2. Beyond that version, react-dnd moved the DragDropContext producing this error.

./node_modules/frontend-collective-react-dnd-scrollzone/lib/index.js
Module not found: Can't resolve 'react-dnd/lib/DragDropContext' in 'X:\WSProjects\sonnys-queue\node_modules\frontend-collective-react-dnd-scrollzone\lib'

@Soundvessel That was due to the CommonJS/ESModule feature, which probably should have been a major version cut (my bad!). You can find it at react-dnd/lib/cjs/DragDropContext or you can import it from the top-level of react-dnd

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

Did anyone find a solution to work with the latest version of react-dnd?

An updated fork of scrollzone (https://github.com/frontend-collective/frontend-collective-react-dnd-scrollzone) works with more modern versions of react-dnd up to and including 7.0.2. Beyond that version, react-dnd moved the DragDropContext producing this error.

./node_modules/frontend-collective-react-dnd-scrollzone/lib/index.js
Module not found: Can't resolve 'react-dnd/lib/DragDropContext' in 'X:\WSProjects\sonnys-queue\node_modules\frontend-collective-react-dnd-scrollzone\lib'

@Soundvessel Did you apply the fix @darthtrevino suggested?

Since I couldn't find a solution out of the box, and some solutions don't work with the latest react-dnd version, I came up with a solution myself: https://gist.github.com/orlandovallejos/ed9c79dd67e96c25cfcc8f1008df9489

I hope it helps someone else.

@orlandovallejos
Hello, could it be implemented on this Sort stress test example? https://react-dnd.github.io/react-dnd/examples/sortable/stress-test

I tried i little but no success.

@MartinN3 Here you have my friend: https://codesandbox.io/s/react-dnd-example-12-s3nnf

https://imgur.com/a/heuPO48

You have to update it for your requirements, offset, div containers (probably more than 1), scrolling speed (using the PX_DIFF variable), etc.

Remember the scrolling feature works out of the box in Chrome.

Since I couldn't find a solution out of the box, and some solutions don't work with the latest react-dnd version, I came up with a solution myself: https://gist.github.com/orlandovallejos/ed9c79dd67e96c25cfcc8f1008df9489

I hope it helps someone else.

This is the best solution. Thank you so much for the solution :)

Was this page helpful?
0 / 5 - 0 ratings