-
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
Remove multi-selection header #2934
Conversation
cc33594
to
e05b90a
Compare
Codecov Report
@@ Coverage Diff @@
## master #2934 +/- ##
==========================================
+ Coverage 34.47% 35.05% +0.57%
==========================================
Files 196 197 +1
Lines 5798 6008 +210
Branches 1021 1078 +57
==========================================
+ Hits 1999 2106 +107
- Misses 3216 3286 +70
- Partials 583 616 +33
Continue to review full report at Codecov.
|
a5aef58
to
d596807
Compare
Thanks for working on this. Very nice! 👍 👍 |
Agreed. IMHO this improves the UI by decreasing the number of UI changes happening after select 👍 |
d596807
to
aefba78
Compare
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 not working on Firefox, a chance I switch to Firefox nightly recently :)
this.props.onSelect(); | ||
// Block could be hovered, not selected. | ||
if ( this.props.uids.length === 1 ) { | ||
this.props.onSelect( this.props.uids[ 0 ] ); |
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.
Not related to this PR but I guess this means we could drop this line https://github.com/WordPress/gutenberg/pull/2934/files#diff-1d765b1a62f4ddc8c86819016031b8dfR23
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.
Yeah, was wondering why there were two calls. Not sure which to delete. The call here is not strictly necessary, it's only needed for the inspector I guess.
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.
No, actually it's necessary when we click on the toggle for a "hovered" block, we need to select it first to avoid issues when trying to click the menu icons.
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 done.
editor/sidebar/index.js
Outdated
@@ -32,6 +32,7 @@ export default connect( | |||
( state ) => { | |||
return { | |||
panel: getActivePanel( state ), | |||
selectedBlockCount: getSelectedBlockCount( state ), |
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.
Should we connect the Header
and the BlockInspector
instead since this is not directly used here?
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.
Sure :)
What's not working exactly? Is it the buttons? Are the working buttons not working for you either? Strange... |
@iseulde Yes, no buttons working, neither the arrow buttons nor the toggle. |
No error, nothing, seems like there's another event handler preceding the ones for the buttons. |
It looks unrelated to this PR, I have the same issue with the arrows on master but this PR makes it worse because we can't delete multi selected blocks now |
Looks like there's a SELECT_BLOCK action... Looking where it's coming from. |
Found it. The padding overlaps. This doesn't trigger a mousedown event in Chrome, but it does in FF. |
I seem to be wrong there. It seems FF is retargeting the focus event. In block.js the event has the |
@youknowriad That should fix it... Not nice to introduce browser specific APIs, but I don't see another way other than adding |
I don't mind the browser specific code if it's commented. Still seeing some issues:
|
Hm, I can't reproduce either issue... |
Tested the event issue sandboxed, and Safari should have the same issue. But multi-selection in safari is broken entirely... 😅 |
Fix that, but then other stuff breaks. I'm in focus hell again. |
Testing this more, I think these issues I'm seeing are related. I can't reproduce them consistently, it happens once in 4/5 tries. But if one happens, it means the second one will happen two. Also, I wonder if it's a z-index issue because I've found that the "trash" icon doesn't get the "cursor" pointer and doesn't change the color when I hover it. (Again not consistently). |
Now that I think about it, I fixed a z-index issue in the Right menu in another PR, I wonder if a rebase would fix at least the "delete" issue. |
@youknowriad Which PR? Already merged? Re Safari, I can push the change here, but in safari I'm having issues where the focus in editable constantly moves. Still have to track that down. |
71455ef
to
44b1966
Compare
editor/modes/visual-editor/block.js
Outdated
@@ -250,14 +250,18 @@ class VisualEditorBlock extends Component { | |||
} | |||
|
|||
onFocus( event ) { | |||
if ( event.target === this.node ) { | |||
// Firefox retargets to parent with tabIndex. | |||
const target = event.nativeEvent.explicitOriginalTarget || event.target; |
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.
Safari also retargets, and no way to get the real target... :/ Maybe we're not supposed to put focusable elements inside a tabIndex="0"
?
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 @afercia knows more about this? :)
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'm not sure nesting focusable elements is a good thing. It's like putting a link inside a link.
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.
Yeah, that's what I think too... This is no good: <div tabindex="0"><button></button></div>
.
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.
Thanks @afercia for the quick feedback! I've removed the nesting in this branch now.
@youknowriad I have no issues in Safari... What's the version? Errors? Any specific steps to reproduce? |
This works quite nicely. I'm not sure if it should be part of this PR or a separate issue, but a problem with this multi block select is that the browser still has a selection but it's not visible to the user. Therefore, if they start typing, some of their text (their selection start point to the end of the first block they selected) disappears and is replaced by what you type, but not all of it. This is probably a confusing user experience. If you think about what users are used to, as soon as they start typing, they would probably expect all selected blocks to be deleted and replaced with what they are typing. Is there an issue for this somewhere? |
Also, I'm hitting the same issue as @gziolo on Chrome. It seems that if you click outside the range of |
Should some of these issues be addressed as part of ongoing work in #2990? |
@ephox-mogran That seems to a regression on this branch, where we keep the focus on the first selected block rather than moving it elsewhere. I'll fix it. I don't necessarily agree that typing should remove all the blocks, but we can discuss that in a separate issue. |
Now it will set focus on the settings menu. Not sure where to best set it for now, but in the future this should probably be that some element as for a cmd/ctrl while in a block (first toolbar element). Also removed hover UI while the user is selecting. |
a0c85ef
to
b807bc2
Compare
Any other action items for this branch? |
{ showUI && isValid && mode === 'visual' && <BlockToolbar uid={ block.uid } /> } | ||
|
||
{ isFirstMultiSelected && ( | ||
{ isFirstMultiSelected && ! this.props.isSelecting && |
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.
Can you explain why do we need the isSelecting
prop? I'm a bit concerned about all these booleans we use here :)
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.
isSelecting
will be true when the user is in the process of selecting, in which case we should update the visual selection, but we shouldn't (yet) show UI or show hover UI during this process.
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.
👍 Do you think it could be tracked in Redux's state instead of a local state?
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.
Sure, we can do that.
className="editor-visual-editor__block-edit" | ||
tabIndex="0" |
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'm a bit concerned about this change (moving the tabIndex here). Because we heavily rely on the .editor-visual-editor__block
being tabbable (for arrow navigation for example). I'll have to test the places we use this className.
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.
Confirmed arrow navigation is broken.
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.
Hm, it's unfortunate that we rely on .editor-visual-editor__block
. :/ We do have to move it because nesting buttons in this is causing bugs in a Firefox and Safari.
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'll update the selector.
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.
Yes, but I don't know honestly what's the best alternative would be. This is all related to focus management which is causing us a lot of trouble in several places. We'll have to rethink it entirely IMO:
- Clarify the role of the focus config in state
- Have clear guidelines on when to rely on DOM imperative focus handling and state-based focus updates.
- All this while ideally hiding everything from the block's author.
I think we should tackle this clarification as soon as we can.
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.
How can I resolve this PR? Should I remove the bug fixes for Firefox and Safari (also broken in master).
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.
It relates more to the Arrow navigation which is causing issue with this PR.
Maybe it's ok to do a temporary hack in this PR, adding a way to identify the block's tabbable element (className or attribute or something else) and update the WritingFlow
component to target this node instead of editor-visual-editor__block
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.
Ah, ok. I'll update the temporary hack in WritingFlow
.
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.
Rewritten in dc9859f2935c5add1d4c10edf45ca916542ff4e1.
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.
Yes, but I don't know honestly what's the best alternative would be. This is all related to focus management which is causing us a lot of trouble in several places. We'll have to rethink it entirely IMO
Noting that I have a local work-in-progress branch which takes a stab at this with a few ideas:
- We don't explicitly target the block class, but rather allow descendant DOM nodes of WritingFlow assign a broadly-understood
data-
attribute which defines a focus context (for a block,data-focus-context={ block.uid }
- State tracks the ID of the current focus context, and when this changes, WritingFlow shifts focus to the first available input within the new context (via
querySelector
) if the context does not already currently have focus - Arrow key navigation works simply by updating the focus ID in state using the closest focus context of the next eligible input, if it is different than the current value, otherwise simply moving focus
- Blocks can still explicitly move focus to inputs (like video block to its caption) by assigning a custom focus context ID to editable, so e.g.
<Editable focusId="caption" />
,setFocus( 'caption' )
As a work-in-progress, some of these ideas are still muddy, for example directionality of focus and shifting focus within the same focus context might be deserving of more controlled treatment within state.
b807bc2
to
cb55280
Compare
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.
Works great! We're getting there
Feel free to update or not the PR to address the minor remaining comments.
cb55280
to
fdea571
Compare
Worth noting 58bd5f7 removed the tabindex and aria-label from the outer containers. That was meant for keyboard navigation through blocks as implemented in #1618 and now currently discussed on #2031 tabindex and aria-label should be used on the containers used for keyboard navigation through blocks: depending on the direction #2031 will take, this should probably be changed. |
@afercia As discussed earlier, we also can't leave a tabIndex on the outer wrapper as long as there are buttons inside it. #2934 (comment) |
@iseulde we should distinguish a bit. Things like: Instead, a focusable container which is part of the layout is a bit different. For example, in WordPress |
See: #2934 See: https://codepen.io/aduth/pen/MQxRME Something needs to capture the focus event, which is skipped by button press on the block's toolbar, but bubbles up wrongly to the parent's edit wrapper (which has tabIndex) and causes parent block to select itself.
See: #2934 See: https://codepen.io/aduth/pen/MQxRME Something needs to capture the focus event, which is skipped by button press on the block's toolbar, but bubbles up wrongly to the parent's edit wrapper (which has tabIndex) and causes parent block to select itself.
* Writing Flow: Select block by own focus handler * Block List: Mark default appender events as block-handled * Writing Flow: ... * Block: Move tabIndex to wrapper component See: #2934 See: https://codepen.io/aduth/pen/MQxRME Something needs to capture the focus event, which is skipped by button press on the block's toolbar, but bubbles up wrongly to the parent's edit wrapper (which has tabIndex) and causes parent block to select itself. * Writing Flow: Update block focusable target * Block: Remove unused block classname constant Originally used for down-to-new-paragraph in #3973, removed as of #5271 * Block List: Capture focus event on block wrapper Corresponding to move of tabIndex from inner edit element to wrapper, we also need to capture focus from wrapper. This way, when focus is applied via WritingFlow, the block appropriately becomes selected. This may also make "onSelect" of movers unnecessary. * Block List: Remove pointer handling of onSelect Can now rely on focus behavior captured from wrapper node to reflect selection onto blocks, even those without their own focusable elements * Block List: Avoid select on focus if in multi-selection Multi-selection causes focus event to be triggered on the block, but at that point `isSelected` is false, so it will trigger `onSelect` and a subsequent `focusTabbables`, thus breaking the intended multi-selection flow. * Block Mover: Remove explicit select on block move Focus will bubble to block wrapper (or in case of Firefox/Safari, where button click itself does not trigger focus, focus on the wrapper itself) to incur self-select. * Block List: Singular select block on clicking multi-selected This reverts commit 90a5dab.
Description
Split off from #1811. This PR remove this multi selection header in favour of inline actions, just like single-selected blocks. Adding inspector tools can be done in a separate PR. See #1811.
How Has This Been Tested?
Checklist: