-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
Block List: Display inserter button after block on hover, focus #2890
Conversation
Codecov Report
@@ Coverage Diff @@
## master #2890 +/- ##
==========================================
+ Coverage 34.07% 34.11% +0.03%
==========================================
Files 192 192
Lines 5675 5710 +35
Branches 996 1004 +8
==========================================
+ Hits 1934 1948 +14
- Misses 3165 3181 +16
- Partials 576 581 +5
Continue to review full report at Codecov.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great job so far.
I noticed a small "glitch" which is not totally related but I think we this change, we have to update the inserter at the bottom of the editor to always insert at the end of the post instead of after the selected block.
editor/inserter/index.js
Outdated
const { opened } = nextState; | ||
if ( | ||
( this.state.opened !== opened || this.props.insertIndex !== insertIndex ) && | ||
Number.isInteger( insertIndex ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When is this second check necessary?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The global and end-of-content inserters don't specify the insertIndex
prop, so this ensures the sibling insertion point is only set for the between-inserters. It might be the case that insertIndex !== undefined
could work well here. I used Number.isInteger
elsewhere to capture 0
but not null
(since JavaScript is a very sensible language where null >= 0
evaluates to true 😆 )
@@ -51,11 +51,11 @@ export class InserterMenu extends Component { | |||
} | |||
|
|||
componentDidMount() { | |||
document.addEventListener( 'keydown', this.onKeyDown ); | |||
document.addEventListener( 'keydown', this.onKeyDown, true ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you explain why this change is necessary?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a similar issue to the one discussed at #2706: Namely, WritingFlow is handling the arrow presses and moving between blocks. The true
argument allows us to handle the key press earlier during the capture phase. I might take another pass at this, and I wonder why we need to bind to the document at all instead of using React events (since I expect bubbling would work better in the latter case). If I keep it as-is, I'll add a clarifying comment.
editor/modes/visual-editor/block.js
Outdated
|
||
if ( isHovered || isSelected || isMultiSelected ) { | ||
if ( isHovered || isSelected || isMultiSelected || isInserterOpen ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess this check is to avoid "removing" the inserter when we hover out of the block?
Maybe we can handle this in a simpler way: select the block when we open its inserter.
I'm just trying to avoid this dependency between the inserter and this component.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we can handle this in a simpler way: select the block when we open its inserter.
That sounds like a good idea! I'll give it a try.
@aduth, thank you for working on this one. In my opinion, this was the biggest UX issues I discovered so far in Gutenberg 🥇 |
Yep, makes sense. I'll change this. |
5bc749e
to
e3e0741
Compare
I tested this PR. I love the changes introduced ❤️ Just saying that this toolbar doesn't play well with this change. I think that the toolbar needs some rethinking, because it also makes it harder to read the previous paragraph /cc @jasmussen The last block looks a bit different, but I think it makes a lot of sense: I can confirm that the last commit fixes issue mentioned by @youknowriad and the add code itself look good to me. |
@jasmussen what if we would move the very last + button to be rendered the same way as all other icons, but it would be always visible? We could also mirror the behavior of the existing + button and show on hover the following: |
name, | ||
insertionPoint | ||
); | ||
class Inserter extends Component { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess we don't need this to be a class component, but probably the same discussion for/against inline props.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I hope we will see the day where there is only one supported way of creating components in React. I feel like some components are converted back and forth whenever requirements change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For me, this is good to ship. There are some UI concerns like pointed out by @gziolo but worth a try. Also, I'll explore the fixed toolbar switch soon which could solve the toolbar issue.
Yes, totally agree we should ship it as it is and continue the discussion here. |
Designwise, I'd like to echo @gziolo's comments, this isn't ideal and it adds some visual load to the block silhuette. I don't want to block this from moving forward — nice work — but it does seem like a half-step. I understand the moving parts — it has to be accessible, it has to be fairly simple codewise, and the previous solution wasn't great either. But interface wise, we are at a point where we should be extremely careful to introduce visual regressions, especially since this is one of the critiques that is (fairly so) leveraged on Gutenberg these days. One of the design patterns of Gutenberg is that it's possible to show further block options when a block is selected. A common editor pattern when you want to insert content in between paragraphs or other elements, is to make a linebreak. Perhaps we could show the inserter when a block is selected? Perhaps we could show an empty line when a block is selected, and have the Enter button put the cursor there? Perhaps both? It seems like it is worth looking at how desktop publishing apps solve this. Either way it's important we strike a balance between something that is easy to implement and solves the problem, with the cognitive load that it adds. In this case it feels like there's an imbalance. This implementation also doesn't solve the inserting images inline (#2043), and it seems like this inserter pattern would've been a good opportunity to look at that. |
As I mentioned above, not having such button available next to each block caused me the biggest struggle when I opened Gutenberg for the first time. I must admit, I got to easily tempted to click Merge button in here :) I will be more cautious next time and wait for a wider feedback whenever we introduce UI/UX changes.
At the moment when you hover over one of the existing blocks you can see arrows which allow moving the block up or down in the document hierarchy: In that context add block button plays a similar function, but as you observed it adds another visual element to the block. Let's continue the discussion in #2925. |
Adding a bit more context as I discussed this one with @aduth in person. The point was to add functionality that allowed the user to insert blocks in between other blocks easily and without hidden interactions. Implementation wise I think we should treat this inserter as a separate element—or at least, visually separate. It should show when we hover the limit area between two blocks. Additionally, it can show up when a block is selected. Something more like this: This is also in anticipation of nested blocks, which would use the pattern of the bottom inserter. |
In trying to imagine how this would operate in practice, I get the sense that it might be frustrating to find the sweet spot between hovering and individual block and hovering between blocks to reveal the inserter. It was already not-great in the implementation which was proposed here. |
Closes #2752
Related: #833
This pull request seeks to display a block inserter after a hovered or focused block, enabling a user to easily insert between blocks. This is a first step toward eventually dropping the header global inserter (#2755).
Design notes:
This is a best-attempt design. Iterations or suggestions are welcome. In particular, the specifics of the clickable/tappable area and hover bounds may need some improvement.
Testing instructions:
Verify that you can insert after a block which is focused or hovered, and that regressions do not otherwise occur with the global inserter or end-of-content inserters.