Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.Sign up
Reorder blocks via drag & drop (v2. using editor dropzones). #4115
This PR aims to introduce drag & drop functionality for rearranging blocks, and potentially for reordering other elements elsewhere in the editor (e.g. image galleries). Relevant issues: #38, #743, #1511.
I am continually updating this description with new issues, screenshots, etc. Last update: 10 March, 2018.
How Has This Been Tested?
Screenshots (jpeg or gifs if applicable):
The screenshots below will be updated accordingly as design/method changes are applied.
Dragging a block from the sides (this is an image from a previous version that includes some transparency in the resulting drag image - the current version doesn't):
Long blocks with height greater than
The underlay div mentioned below:
The inner underlay that depicts the actual gray area shown while dragging:
Types of Changes
This PR does not introduce external dependencies and instead attempts to make due with the current dropzones.
Most changes involve adding drag handlers to the block components. A Higher Order Component (HOC) has been added that provides drag initialisation/end handlers ( onDragStart and onDragEnd properties ) to the wrapped component (in this case, the block-list layout). DragOver is handled by the HOC and need not be fiddled with in the wrapped component. Drop handlers and styling are handled by the wrapped component. See the HOC's README file for further details. An action listener and reducer have been added to the store for reindexing a block when dropped onto one of the existing drop zones.
An underlay div (along an invisible inner div with grey background) was added to the block component and sits behind the rest of the controls. This essentially wraps the block area and responds to drag evens (see third image above for a more visual depiction). The same drag handlers have been added to the block-mover (up/down arrows) and block settings (ellipsis) components, so that users can grab the block from the mover controls as well.
There are 4 steps to the reordering process:
Currently tested with latest:
Unless otherwise stated in the issues below, functionality is consistent across these browsers.
Non-Blocking, Candidate Enhancements:
You posted a screencast in Slack that's looking really good. Very nice work!
A few wishlist items for the implementation of block drag and drop:
A bunch of us are going on holiday and won't return until early in the new year, so I hope you can be patient about reviews until then
Hey Joen! Thank you very much for your detailed response. This is exactly the type of feedback I wanted at this point
The purple area is what responds to the drag event, but it currently sits in the background so that it doesn't take precedence over other drag events (i.e. resizing images). I haven't really put any thought on making the whole block draggable, so this was just a quick assembly. We can definitely investigate tweaking z-indexes and adding flags where necessary to give a broader drag handle.
I haven't tried yet, but definitely aim for this to support the browsers in our list or fail gracefully.
It's in my list of things to do/investigate next. So we will have (hopefully) some sort of scrolling, although we may need something more than scrolling for the 20 pages case. Imagine you scroll 19 pages and drop the handle... that would not be so nice
Indeed. I do plan to investigate touch handling, so maybe once we are pixel perfect for desktop we can discuss how to incorporate this for mobile. I also need to work on desktop narrow view, as I have only fiddled with a wide viewport right now.
No problem! I just used F8F8F8 in the prototype.
Shouldn't be a problem to fix. I can add an inner underlay and only show that when dragging - and we can adjust its size as we like.
Yes, although I haven't had time to look deeper into this, so it may not be a big issue eventually. The problem that I seem to had was as follows:
We take a snapshot of the DOM element (block) and that is what goes in the preview. So whatever we use for preview has to be visible at the time. Adding the shadow created a sort of flickering effect (in that we add the shadow, take the snapshot, and then hide the element). It didn't feel natural, so I may need to find an alternative solution. Might also be that I do not clone the DOM element currently - I just use it for the snapshot and then hide it. I have read that others clone the element, place it somewhere visible on the page (visible to the browser, not the user - so effectively outside the viewport).
So this is something that I need to investigate. I do not know the solution or the sort of problems that may arise from cloning a DOM element - but will definitely try a few things out.
We also have full opacity in the mocks, but we get a transparent image in the prototype, so there's that too
Nit a problem. Will look into this.
Not a problem at all. I believe I have enough feedback now to carry on
Sometimes when I need to animate something, like a shadow appearing, I apply an invisible box shadow to the element, always there, like
Might that work? In any case, not critical, but something to think about.
Nice! I think that's a great idea. I will experiment with it next.
referenced this pull request
Dec 27, 2017
@youknowriad I notice a minor inconsistency with the latest branch. Although the grab handle is shown when hovering over the inserter and ellipsis menu, I can’t seem to grab the block from there. We may as well not show it then if that functionality's been removed. (sorry that i just noticed this - browser: chrome)
p.s. there was a bit of discussion earlier with Nikolay and Joen about enabling grabbing from there, and it was eventually consistent in all browsers in terms of functionality.
Quibbling at this point. I'd like to see this merged. I think it could still use some continued polish, though we can do so iteratively. Particularly around: impulsive additions of
cursor styles, burden of consuming component in integrating Draggable.
In final testing, I also found I'm still seeing the "grab" cursor become permanently stuck, though I have not been able to find consistent steps for reproducing.