diff --git a/packages/block-editor/src/components/block-list/block.native.js b/packages/block-editor/src/components/block-list/block.native.js index c6cce290985c22..03a84d530ba12a 100644 --- a/packages/block-editor/src/components/block-list/block.native.js +++ b/packages/block-editor/src/components/block-list/block.native.js @@ -605,6 +605,8 @@ const applyWithDispatch = withDispatch( ( dispatch, ownProps, registry ) => { } moveFirstItemUp( rootClientId ); + } else { + removeBlock( clientId ); } } }, diff --git a/packages/block-editor/src/components/rich-text/index.native.js b/packages/block-editor/src/components/rich-text/index.native.js index aab10e9ab65476..9427962eced198 100644 --- a/packages/block-editor/src/components/rich-text/index.native.js +++ b/packages/block-editor/src/components/rich-text/index.native.js @@ -223,7 +223,7 @@ function RichTextWrapper( // an intentional user interaction distinguishing between Backspace and // Delete to remove the empty field, but also to avoid merge & remove // causing destruction of two fields (merge, then removed merged). - if ( onRemove && isEmpty( value ) && isReverse ) { + else if ( onRemove && isEmpty( value ) && isReverse ) { onRemove( ! isReverse ); } }, diff --git a/packages/block-editor/src/components/rich-text/native/index.native.js b/packages/block-editor/src/components/rich-text/native/index.native.js index 2381b9809eca86..ab465b24411549 100644 --- a/packages/block-editor/src/components/rich-text/native/index.native.js +++ b/packages/block-editor/src/components/rich-text/native/index.native.js @@ -650,6 +650,40 @@ export class RichText extends Component { return shouldDrop; } + /** + * Determines whether the text input should receive focus after an update. + * For cases where a RichText with a value is merged with an empty one. + * + * @param {Object} prevProps - The previous props of the component. + * @return {boolean} True if the text input should receive focus, false otherwise. + */ + shouldFocusTextInputAfterMerge( prevProps ) { + const { + __unstableIsSelected: isSelected, + blockIsSelected, + selectionStart, + selectionEnd, + __unstableMobileNoFocusOnMount, + } = this.props; + + const { + __unstableIsSelected: prevIsSelected, + blockIsSelected: prevBlockIsSelected, + } = prevProps; + + const noSelectionValues = + selectionStart === undefined && selectionEnd === undefined; + const textInputWasNotFocused = ! prevIsSelected && ! isSelected; + + return ( + ! __unstableMobileNoFocusOnMount && + noSelectionValues && + textInputWasNotFocused && + ! prevBlockIsSelected && + blockIsSelected + ); + } + onSelectionChangeFromAztec( start, end, text, event ) { if ( this.shouldDropEventFromAztec( event, 'onSelectionChange' ) ) { return; @@ -843,9 +877,8 @@ export class RichText extends Component { if ( this.props.value !== this.value ) { this.value = this.props.value; } - const { __unstableIsSelected: isSelected } = this.props; - const { __unstableIsSelected: prevIsSelected } = prevProps; + const { __unstableIsSelected: isSelected } = this.props; if ( isSelected && ! prevIsSelected ) { this._editor.focus(); @@ -855,6 +888,16 @@ export class RichText extends Component { this.props.selectionStart || 0, this.props.selectionEnd || 0 ); + } else if ( this.shouldFocusTextInputAfterMerge( prevProps ) ) { + // Since this is happening when merging blocks, the selection should be at the last character position. + // As a fallback the internal selectionEnd value is used. + const lastCharacterPosition = + this.value?.length ?? this.selectionEnd; + this._editor.focus(); + this.props.onSelectionChange( + lastCharacterPosition, + lastCharacterPosition + ); } else if ( ! isSelected && prevIsSelected ) { this._editor.blur(); } diff --git a/packages/block-library/src/buttons/test/__snapshots__/edit.native.js.snap b/packages/block-library/src/buttons/test/__snapshots__/edit.native.js.snap index 25867634d12d8e..1a55c807225d9d 100644 --- a/packages/block-library/src/buttons/test/__snapshots__/edit.native.js.snap +++ b/packages/block-library/src/buttons/test/__snapshots__/edit.native.js.snap @@ -71,9 +71,3 @@ exports[`Buttons block when a button is shown removing button along with buttons
" `; - -exports[`Buttons block when a button is shown removing button along with buttons block removes the button and buttons block when deleting the block using the delete (backspace) key 1`] = ` -" - -" -`; diff --git a/packages/block-library/src/buttons/test/edit.native.js b/packages/block-library/src/buttons/test/edit.native.js index 2fe70d034aa747..f393a31c7330ad 100644 --- a/packages/block-library/src/buttons/test/edit.native.js +++ b/packages/block-library/src/buttons/test/edit.native.js @@ -18,7 +18,6 @@ import { */ import { getBlockTypes, unregisterBlockType } from '@wordpress/blocks'; import { registerCoreBlocks } from '@wordpress/block-library'; -import { BACKSPACE } from '@wordpress/keycodes'; const BUTTONS_HTML = ` @@ -238,32 +237,6 @@ describe( 'Buttons block', () => { expect( getEditorHtml() ).toMatchSnapshot(); } ); - - it( 'removes the button and buttons block when deleting the block using the delete (backspace) key', async () => { - const screen = await initializeEditor( { - initialHtml: BUTTONS_HTML, - } ); - - // Get block - const buttonsBlock = await getBlock( screen, 'Buttons' ); - triggerBlockListLayout( buttonsBlock ); - - // Get inner button block - const buttonBlock = await getBlock( screen, 'Button' ); - fireEvent.press( buttonBlock ); - - const buttonInput = - within( buttonBlock ).getByLabelText( 'Text input. Empty' ); - - // Delete block - fireEvent( buttonInput, 'onKeyDown', { - nativeEvent: {}, - preventDefault() {}, - keyCode: BACKSPACE, - } ); - - expect( getEditorHtml() ).toMatchSnapshot(); - } ); } ); } ); diff --git a/packages/block-library/src/heading/test/__snapshots__/index.native.js.snap b/packages/block-library/src/heading/test/__snapshots__/index.native.js.snap index 308aa8ac729bff..c0397e823d4511 100644 --- a/packages/block-library/src/heading/test/__snapshots__/index.native.js.snap +++ b/packages/block-library/src/heading/test/__snapshots__/index.native.js.snap @@ -6,6 +6,12 @@ exports[`Heading block inserts block 1`] = ` " `; +exports[`Heading block should merge with an empty Paragraph block and keep being the Heading block 1`] = ` +" +