-
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
Writing Flow: 'Down' key at bottom creates new paragraph #3973
Conversation
I love it! All of these little flow improvements really add up, and this is a nice one. I still think we need #3078 so you can also click at the end of a block list (after an image block for example), but this feels like it ties into that. Looks like there's a visual regression in the blockquote citation. The font should be smaller and gray, which it is 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.
Some questions:
Do you think we should allow this behavior on "text" blocks only (all blocks with caret) or we should use "enter" in these cases?
If we were to do so, why it's not working on empty paragraphs?
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import './style.scss'; | ||
import BlockDropZone from '../block-drop-zone'; | ||
import { insertBlock } from '../../actions'; | ||
import { appendDefaultBlock } from '../../actions'; | ||
import { getBlockCount } from '../../selectors'; | ||
|
||
export class DefaultBlockAppender 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 this could be a functional component now :)
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.
My thinking too, but jest wasn't happy and I left for the sake of opening the PR :)
Not sure what you mean. Do you mean should the
Similarly to how #3623 had this issue with endless appending, the current implementation bails if the last tabbable is empty. One glaring issue with that is the following, which can be reproduced:
Perhaps we can be smarter and look not just at the last tabbable (in this case, the |
56e22cd addresses my previous comment:
|
Well! actually the opposite (I wrote the opposite of what I was thinking :) ). It should append a default block only when the block before is not a textual block because in a textual block (think a unique text area for everything), clicking ↓ does not create an empty line. But I can be on board with the current behavior, just wanted to bring this up :) |
} | ||
|
||
// Find block-level ancestor of said last tabbable | ||
const blockEl = lastTabbable.closest( '.editor-block-list__block-edit' ); |
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 use a const for the classname as it's being used in several places.
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.
@youknowriad, what do you think of 31f9e0a35eb7a46b7749e12baf35779dfefa72b9? As an alternative to spinning up a constants
file, etc.
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 love it
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.
Left some optional comments but this is nice
@@ -532,6 +532,8 @@ const mapDispatchToProps = ( dispatch, ownProps ) => ( { | |||
}, | |||
} ); | |||
|
|||
BlockListBlock.className = 'editor-block-list__block-edit'; |
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.
❤️
31f9e0a
to
59da174
Compare
I see the regression, but I'm also seeing it in |
editor/effects.js
Outdated
@@ -388,4 +390,8 @@ export default { | |||
dispatch( saveReusableBlock( reusableBlock.id ) ); | |||
dispatch( replaceBlocks( [ oldBlock.uid ], [ newBlock ] ) ); | |||
}, | |||
APPEND_DEFAULT_BLOCK( action, store ) { | |||
const { dispatch } = store; | |||
dispatch( insertBlock( createBlock( getDefaultBlockName() ) ) ); |
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.
Minor: Effects can simply return
an action object to dispatch, if they're synchronous.
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, good tip, easy to forget.
|
||
return blockDescendants.some( isElementNonEmpty ); | ||
|
||
function isElementNonEmpty( el ) { |
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.
Minor: Based on its name, I'd be inclined to expect typeof isElementNonEmpty( el ) === 'boolean'
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.
Hoisting mechanics are non-obvious 😬 Would it be sensible to move this to the top of the function, or out of it?
.slice( blockIndex + 1 ) | ||
.filter( ( el ) => blockEl.contains( el ) ); | ||
|
||
return blockDescendants.some( isElementNonEmpty ); |
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.
Minor: Seems an optimization could check both blockEl.contains
and isElementNonEmpty
in the same Array#some
, instead of the separate Array#filter
.
Fixes the following issue introduced by the parent commits: 1. Add a Quote block. 2. Fill out quote but not citation. 3. Keeping pressing ↓, hoping to move into an empty appendage, but nothing happens. Also correctly account for block-level-only tabbables, e.g. Image.
59da174
to
9894675
Compare
All good tips, @aduth. Amended. |
This is cool, nice work. |
* 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
Keyboard-only alternative to #3623 (see #3078).
↓
focuses a brand new paragraph (or whichever is the default block type).Enter
at the edge of the block, but this isn't the case for other blocks.Enter
at the edge of a Quote block just adds a line within the citation field of that Quote. And whileEnter
does work for e.g. Image, right now this isn't visually clear (see Try adding focus outline for blocks that don't have input fields #3951 for improvements).Enter
events and append an empty block, but maybe there is value in adding this↓
-based mechanism—regardless ofEnter
improvements.How Has This Been Tested?
Enter
to move on to a new paragraph (or indeed any block thanks to/
autocompletion, which I use with a passion).Enter
adds a line break within citation, so pressBackspace
to undo↓
, notice how the caret has moved into a new empty block.Screenshots (jpeg or gifs if applicable):
Types of changes
Writing flow enhancement.
Checklist: