Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow sorting blocks through Drag & Drop #38

Closed
diegoliv opened this issue Feb 9, 2017 · 43 comments
Closed

Allow sorting blocks through Drag & Drop #38

diegoliv opened this issue Feb 9, 2017 · 43 comments
Labels
Customization Issues related to Phase 2: Customization efforts [Type] Enhancement A suggestion for improvement.

Comments

@diegoliv
Copy link

diegoliv commented Feb 9, 2017

The arrow will work fine for mobile, but for desktop, probably most users will want to sort blocks with a drag & drop approach.

@JDGrimes
Copy link
Contributor

JDGrimes commented Feb 9, 2017

I noticed that the image block can apparently already be dragged. After discovering that I was expecting all of the block types to be draggable as well.

@diegoliv
Copy link
Author

diegoliv commented Feb 9, 2017

Yep, and if you select all the text inside a text block, you can drag it and drop it on other places. I tried it, but most of the time, it ended dropping the content inside another block.

Probably the best way to solve this is to have some sort of handler (maybe at the left of the block) which the user would use to drag the hole block.

@jasmussen
Copy link
Contributor

Drag and drop would be a nice progressive enhancement on top of arrows and shortcut keys!

I'm noodling on a different look for block and inline level formatting controls, based on feedback about the popup toolbars. But in the current UI (which, let's keep for the prototype to get proper feedback on it), we could do something like this:

screen shot 2017-02-10 at 14 15 53

That is, extend the block level toolbar ever so slightly with a label for what you're looking at, providing a draggable area.

@jasmussen
Copy link
Contributor

Here's another mockup:

formatting hover

Hover a block to reveal switcher, up/down arrows, and along the top of the edge, a tiny grid of dots indicating a draggable area.

@JohnPixle
Copy link

JohnPixle commented Feb 14, 2017

Hi people. I was playing around with image mockups at inVision, and created a short flow that shows drag control on hover.

It also explores the idea of showing another set of actions on hover on the right side. Actions like duplicate a block, delete, split in columns etc. I am not sure if all these actions are a stretch at this point but here is a 10sec video: https://cl.ly/jAEr

I'll be happy to explore this further.

@melchoyce
Copy link
Contributor

Quick riff on @jasmussen's mockup:

screen shot 2017-02-15 at 11 59 17 am

screen shot 2017-02-15 at 11 58 08 am

@jasmussen
Copy link
Contributor

jasmussen commented Feb 15, 2017

❤️ thanks for that riff Mel!

Mark just voiced a well-formulated concern about the blocks feeling "too heavy". If we, after having used the prototypes for a good long while, feel the same way, perhaps we should consider integrating the type switcher in the block level controls as @JohnPixle did in the mockup above, to limit the floating side UI to just arrows and drag handles. That feels especially true with bigger drag handles.

@melchoyce
Copy link
Contributor

They do feel quite heavy, yeah.

@JohnPixle
Copy link

Continuing from Slack I would like to point out the comment from @melchoyce and share a screenshot comparing Medium and Gutenberg contextual toolbars.

alt text

I believe this is related to the overall block weight issue. Not only visually, but heavy in a sense of

Showing both the contextual styling toolbar and the block controls + border at the same time is a bit too much if we indeed want to follow the “just write” flow mentioned earlier at the blog.

Quite unsure on how to overcome this, only testing will show.
Will explore this further design-wise and let you know what I come up with.

John

@JohnPixle
Copy link

Following up to this, I have been brainstorming with myself about the most efficient options/UI elements shown to the user at each of the 4 states:

  1. When the user is actively editing the block (writing flow)
  2. When highlighting text (contextual toolbar)
  3. When hovering a block
  4. When clicking on a block

Can we contextually isolate the options for each of the interaction levels above, so that we only show a minimal but useful amount of tools and options to the user?

Each of the decisions taken for every of the above states will define the weight of the block. If a block gets too heavy, and the page is composed of many blocks, we have a heavy page. The weight metaphor here might not only refer to visual information, or in regards to performance. It might depend on the editing levels that is provided for each interaction stage with the block.

UI elements for Block Hover

There is a text block. What might someone want to do to a text block apart from editing the content? Can we provide the options the user needs at this very first level of interaction? Should this UI accommodate only for the hover state, or it should remain when the block is in focus as well? Should these apply to all blocks globally? Should we find a consistent hover vocabulary for all blocks?

Possible actions on hover would be:

  • Change the block type (convert to a quote instead of paragraph)
  • Move/reorder the block (either with arrows or with dragging. Maybe both)
  • Delete it (perhaps with a click-and-backspace pattern as has been suggested, or a trash bin?)
  • Perhaps duplicate a block

If the above assumptions are correct (they are assumptions for now), then we evaluate how and where to show these elements/buttons.

(important: in the hover case, we should not forget that the borders of the block would(or would not) appear. I am referring to the block element’s box that currently appear on the prototype.

This prototype: https://iseulde.github.io/editor-blocks/ does not give any hover options on hover. This is interesting and helps with the problem of an indeed busy editor screen with som many hovers. This approach though has the cost of not-direct manipulation of the block.

UI elements for Block Click

Now, what happens when you click on a block. What is the UI? Is it progressive and adds up to the already existing hover UI?

Apart from the case of writing, one would click block either to edit the content as a cohesive entity (text alignment or image floats in the case of image block) OR manipulate individual elements by highlighting them and using the contextual toolbar (Bold, Italics, etc). SO for the case of a text block, one possible UI set for the clicked blocked state could be:

  • Alignment tools (applies to all block content)
  • Clicking on the block and hitting backspace could easily in
  • Consider keeping elements from the previous UI state (hover) such as block type switcher
  • The block border/outline could exist or not

UI elements in writing flow

I am all in for the optimal writing flow approach. When the user starts to type I would hide everything except for the circled + icon which adds a new block.

UI elements on Highlight

Highlighting text brings up the contextual toolbar. Would like to explore flows and ideas that do not show both control types (block and contextual). Or at least display them in a consistent, non-obtrusive way.

To summarize, I believe it's a matter of first evaluating the options/needs of the user at each of the 4 interaction states (hover/click/write). We could user-test several scenarios and adapt accordingly.

Sorry for the long post, I would love to hear your input on any of these.

@jasmussen
Copy link
Contributor

SOLID brainstorm work. I think the different categories of actions you've come up with make a lot of sense.

As a quick preface — we should be mindful about hover, and always keep mobile in mind. We should use it as sparingly as possible. But when you are on a big desktop screen, we should also consider not limiting ourselves out of the dogmatic view that any hover enhancement is off the table. For example, hovering between two blocks to insert a new one is a nice desktop enhancement to make, so long as you do the same on mobile (put cursor where you want a block, click (+) ).

Some quick ones:

[deleting a block] (perhaps with a click-and-backspace pattern as has been suggested, or a trash bin?)

Backspace seems obvious here for now, then we can revisit a trash bin if it becomes necessary after testing.

Perhaps duplicate a block

Same — the browser Cut/Copy/Paste tools should probably suffice, and if they don't we can revisit.

Incidentally the whole writing flow can be really helpful as we explore what we show on hover and on click. When you are on desktop, I think it's important to show the rearrangement controls so you don't have to click in first. Formatting can then appear on click. The switcher is an unknown — does this need to exist on hover, or is it okay to show this only on click? The answer will probably present itself as we move forward.

Here are two recent mockups on hover and click:

https://raw.githubusercontent.com/WordPress/gutenberg/5e50c86e0c5c53cd2245e92537e8931cdc0cb317/mockups/Formatting%2C%20Hover.png

https://raw.githubusercontent.com/WordPress/gutenberg/5e50c86e0c5c53cd2245e92537e8931cdc0cb317/mockups/Formatting%2C%20Click.png

See also this clickable slideshow-prototype I put together for a writing flow:

https://projects.invisionapp.com/share/NMAHISEE5#/screens/219366717

@JohnPixle
Copy link

Thanks for putting these together. The inVision prototype is great, love the simplicity of adding a citation to the quote right away. Great points all the way.

@jasmussen
Copy link
Contributor

Added an animatic for a draggable area in #90 (comment).

@jasmussen
Copy link
Contributor

Quick mockup for what a block looks like when being dragged:

drag and drop

See also the animatic in the previous comment 👆

@karmatosed
Copy link
Member

Can we contextually isolate the options for each of the interaction levels above, so that we only show a minimal but useful amount of tools and options to the user?

This comment by @JohnPixle really resonates with me. I keep thinking lately about how magic the editor should be. This to me is where we can bring some of that 'wow it just knew' in. I'm chasing to think of this as 'Predictive Editing', something it seems like the current direction is heading. If done right, I think users will love this.

@jasmussen
Copy link
Contributor

Another mockup that puts the draggable area along the left side of the block, on hover:

drag and drop

@JohnPixle
Copy link

This to me is where we can bring some of that 'wow it just knew' in. I'm chasing to think of this as 'Predictive Editing', something it seems like the current direction is heading.

I think @karmatosed made a great point here adding the predictive character that the editor might potentially need to have. If this is done right, and we achieve a mutual predictive model among the editor and the user, we then have a fine-tuned, truly un-interrupted writing flow. The editor predicts user's next move, and the user predicts (ideally with no effort) the behaviour of the editor (what shall i do in order to achieve [task])

I hope I am not off topic here, but regarding this, I believe that the blocks metaphor might be able to help with enhancing predictability through a metaphor. One knows from real life how a block might behave. Can we extract how a user's model might behave in the editor context?
Not sure if it is worth looking into the idea of enhancing this concept or not, and how one would achieve it while maintaining a fairly clean UI.

@jasmussen
Copy link
Contributor

Great ideas here @karmatosed and @JohnPixle. It truly ties into the whole "everything in its right place" thing I've had on my brain for months now. There's a great song for it too!

https://vimeo.com/157296965

Probably worth grounding it in the near term, and make it feel predictive. Whenever there's a button or feature, worth asking: what's the right place for this? Embracing the block metaphor itself is a step in this direction; we can show the cite attribute only when you are working with quote blocks. That's the right place.

@karmatosed
Copy link
Member

karmatosed commented Feb 20, 2017

we then have a fine-tuned, truly un-interrupted writing flow. The editor predicts user's next move, and the user predicts (ideally with no effort) the behaviour of the editor (what shall i do in order to achieve [task])

Yes! It just flows :)

@jasmussen that song is now the soundtrack of the editor :)

Whenever there's a button or feature, worth asking: what's the right place for this? Embracing the block metaphor itself is a step in this direction; we can show the cite attribute only when you are working with quote blocks. That's the right place.

So much yes :)

@metricjs
Copy link

metricjs commented Mar 8, 2017

I think another consideration here is should users be able to drag multiple blocks at once? I know if I had 5 paragraphs to move around, I certainly wouldn't want to have to move them all separately. This ties in with #62 (Multiple Block Selection). Looking at the ideas on both tickets, I think the last mockup by @jasmussen would combine best with the demos in 62, because the long draggable area could stretch the whole height of the box surrounding the multiple blocks. This would both help make it clear which blocks are being moved and if the height of the multiple selected blocks is taller than the user's window, it ensures they can always see and access the drag handle. If the drag handle was just a button, it may need to move around so it's always visible.

@ellatrix
Copy link
Member

Blocks can now be dragged with the left and right border in https://wordpress.github.io/gutenberg/tinymce-single/
Not sure if it's discoverable enough though. Still need to enable multi block dragging.

@ellatrix
Copy link
Member

Another thing we could do is allowing people to use the arrows both for clicking and dragging.

@mathetos
Copy link

I just tested the beta plugin and thought that drag and drop would be desireable. But when I actually tested it (you can see here my surprise here: https://youtu.be/jXRPTyZnBwA?t=3m ) the arrows were very easy to use. You'll hear in the screencast that often "dropping" an item where you want can be buggy. So I was overall surprised how easy it was to re-arrange the blocks with only the arrows and no drag and drop. As @nylen mentioned, drag and drop is actually more moves than just using the arrows in this case.

So, one voice of concern for drag and drop being not only more UI, but also perhaps not as easy as it is currently.

@buzztone
Copy link

buzztone commented Jun 23, 2017

Step 2 is incredibly difficult to get right, and requires a lot of complicated behaviors like duplicating an item (or at least its general shape and size), scroll handling, and determining the intended new location, especially at the beginning and end of the content.

We're using Drag and Drop for React http://react-dnd.github.io/react-dnd on the Visual Editor for CF7 we are currently developing.

We've found it's pretty solid for simple dragging & dropping in a vertical direction on desktop, which could be a relatively simple but useful enhancement to the current arrows for now.

@carlhancock
Copy link

The up/down arrows are obviously needed for accessibility, but drag-n-drop of content blocks is a must have feature. I've seen comments about how the arrows will work fine for mobile, but if anything drag-n-drop is even more ideal for mobile because mobile devices are all touch screens so drag-n-drop is far more natural for moving elements around than clicking up/down arrows repeatedly.

I come at this from 8 years working on a highly successful drag-n-drop form builder. There is absolutely no way we could have got away with having a visual form builder that required a cumbersome clicking of up/down arrows to reposition existing fields. It would be simply too cumbersome. Not having drag-n-drop of content blocks kind of defeats the whole point of having a pretty nextgen visual editor.

@jwold
Copy link

jwold commented Jun 28, 2017

I come at this from 8 years working on a highly successful drag-n-drop form builder.

Having used Gravity Forms for years on a bunch of projects, I can attest that the drag and drop feature made such a task a LOT easier.

@StaggerLeee
Copy link

How did you manage to make sorting via arrows not move block even a single pixel. Allways in the center and steady.
Amazing work you do. I got sold on Gutenberg from first time I saw it.

@rmccue
Copy link
Contributor

rmccue commented Jul 3, 2017

Step 2 is incredibly difficult to get right, and requires a lot of complicated behaviors like duplicating an item (or at least its general shape and size), scroll handling, and determining the intended new location, especially at the beginning and end of the content.

FWIW, I have some solid code from an internal block-based editor we built at @humanmade which handles drag-and-drop (also as an enhancement to an arrow-based system). If there's interest, I can look at making this open source.

We ended up with a pretty decent system that works by suspending the browser's layout engine:

On mousedown, we measure the current height of the container and set it explicitly on the container. We also measure each item's current offset from the top of the container, and absolutely position it at the exact same spot, and also store the height of each block. This is a slightly-expensive operation, but it happens when the user initially clicks the block, so it doesn't cause drag-lag.

When the cursor moves, we use translations to have the block move on a single axis in a highly performant way. Other blocks are additionally moved out of the way by translating using the stored height to create a gap (which acts as the drop target). These translations can also be animated. (We used Velocity.js for the animation, but native animation works just as well.) Because the browser's layout engine is "suspended", there are no painful reflows, which are usually what cause drag-lag.

When the block is dropped, we already know exactly where it needs to be. We first reorder the DOM to move the block to the correct position, then un-suspend the layout.

(The toughest challenge was moving blocks with Plupload elements inside them, as it really doesn't like being removed from the DOM. Our eventual solution used only a single DOM insertBefore call when dropping, which avoided the typical issues with traditional DnD libraries.)

With that said, that's the technical implementation; the UX is the tough part. This solution does allow a lot of flexibility in terms of what you can implement though.

@hedgefield
Copy link

Please yes, drag and drop would make quickly rearranging content much more intuitive, like Trello/Meistertask/Waffle do.

@jasmussen
Copy link
Contributor

Here are some fresh mockups for how drag and drop could look today.

1: hover near the edge of a block to reveal a grab hand

dragondrop 01 hover near edge

2: grab the block, lift it off the page

dragondrop 02 lift

3: dropzone indicators appear where you can release the block

dragondrop 03 dropzone indicator

The above mockups are optimized for making the page minimally jumpy. As such there's a gray "inset" where the block you're currently dragging around used to sit. There's also a blue dropzone indicator, same as the one you see when you drag an image from the desktop into the editor.

@StaggerLeee
Copy link

Maybe better to have some drag & drop indicator icon ?

@jwold
Copy link

jwold commented Dec 11, 2017

As such there's a gray "inset" where the block you're currently dragging around used to sit. There's also a blue dropzone indicator, same as the one you see when you drag an image from the desktop into the editor.

Love this! Would like to see how it "feels" in practice, but the idea of this is great.

@carlhancock
Copy link

@jasmussen Good start! I'm assuming the "grab handle" would be the entire grey border on all 4 sides? Any thoughts on how this would work on touchscreen devices going this route as the block UI isn't visible until you select a block to give it focus.

Ideally, on a touchscreen device you could drag-n-drop blocks in Gutenberg the way you can drag-n-drop cards in Trello. Which may require different JS behavior for those devices because you'd likely want the entire block to be the grab handle for drag-n-drop purposes and then tapping to select an individual block to initiate the block edit UI.

@jasmussen
Copy link
Contributor

jasmussen commented Dec 12, 2017

I'm assuming the "grab handle" would be the entire grey border on all 4 sides?

Yes. If you have no blocks selected and hover the block, I'm not entirely sure whether it's just that draggable separator line left and right of the block, but if the block is selected and showing full block boundaries, yes absolutely all 4 sides. And also, we want to make this grabbable area as thick as we can, so it's not just a 1px draggable border.

Any thoughts on how this would work on touchscreen devices going this route as the block UI isn't visible until you select a block to give it focus.

Generally I'd defer to the programmer implementing this, on what the best approach is. In my experience, drag and drop especially on phones is very fiddly and usually only good for small blocks like rearranging items in a list block (for which we'd wait for a nested blocks feature to take full advantage of). As soon as you have to drag a block far enough that it also has to scroll the screen, it gets iffy.

That said, I have the following mockup (based on a concept by @iamthomasbishop) which shows the mover, trash and cog on block click and below the content (kinda like how the caption pops out when you select an image). In this case, you could imagine a draggable area popping out too, perhaps a little dot grid left of the movers:

mobile float controls

@karmatosed karmatosed added this to the Feature complete milestone Jan 25, 2018
@mtias mtias removed the [Priority] Low Used to indicate that the issue at hand isn't a top priority to address and can be handled later label Jan 26, 2018
@mtias mtias removed this from the Feature Complete milestone Jan 26, 2018
@jeffpaul jeffpaul added this to the Feature Complete milestone Feb 8, 2018
@mtias
Copy link
Member

mtias commented Apr 3, 2018

Done in #4115.

@mtias mtias closed this as completed Apr 3, 2018
hypest added a commit that referenced this issue Nov 2, 2018
…resolver

Remove the i18n babel module resolver, @wordpress/i18n is now pulled from the git repository
hypest pushed a commit that referenced this issue Nov 2, 2018
…ound-in-ios

Removes the test initialization values for Aztec iOS.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Customization Issues related to Phase 2: Customization efforts [Type] Enhancement A suggestion for improvement.
Projects
None yet
Development

No branches or pull requests