From b9216115dcde8d2498e79dcd58397920a8c03700 Mon Sep 17 00:00:00 2001 From: Andrew Serong <14988353+andrewserong@users.noreply.github.com> Date: Thu, 1 Feb 2024 14:32:47 +1100 Subject: [PATCH] List View: Fix error when switching between template preview modes --- .../src/components/list-view/block.js | 88 ++++++++++--------- 1 file changed, 48 insertions(+), 40 deletions(-) diff --git a/packages/block-editor/src/components/list-view/block.js b/packages/block-editor/src/components/list-view/block.js index 6dedabb48f8b85..0ee7d6b4f3da8c 100644 --- a/packages/block-editor/src/components/list-view/block.js +++ b/packages/block-editor/src/components/list-view/block.js @@ -108,25 +108,6 @@ function ListViewBlock( { blockEditingMode === 'default'; const instanceId = useInstanceId( ListViewBlock ); const descriptionId = `list-view-block-select-button__${ instanceId }`; - const blockPositionDescription = getBlockPositionDescription( - position, - siblingBlockCount, - level - ); - - const blockAriaLabel = isLocked - ? sprintf( - // translators: %s: The title of the block. This string indicates a link to select the locked block. - __( '%s (locked)' ), - blockTitle - ) - : blockTitle; - - const settingsAriaLabel = sprintf( - // translators: %s: The title of the block. - __( 'Options for %s' ), - blockTitle - ); const { expand, @@ -138,18 +119,6 @@ function ListViewBlock( { treeGridElementRef, } = useListViewContext(); - const hasSiblings = siblingBlockCount > 0; - const hasRenderedMovers = showBlockMovers && hasSiblings; - const moverCellClassName = classnames( - 'block-editor-list-view-block__mover-cell', - { 'is-visible': isHovered || isSelected } - ); - - const listViewBlockSettingsClassName = classnames( - 'block-editor-list-view-block__menu-cell', - { 'is-visible': isHovered || isFirstSelectedBlock } - ); - // If multiple blocks are selected, deselect all blocks when the user // presses the escape key. const onKeyDown = ( event ) => { @@ -256,6 +225,54 @@ function ListViewBlock( { setSettingsAnchorRect( undefined ); }, [ setSettingsAnchorRect ] ); + // Pass in a ref to the row, so that it can be scrolled + // into view when selected. For long lists, the placeholder for the + // selected block is also observed, within ListViewLeafPlaceholder. + useListViewScrollIntoView( { + isSelected, + rowItemRef: rowRef, + selectedClientIds, + } ); + + // When switching between rendering modes (such as template preview and content only), + // it is possible for a block to temporarily be unavailable. In this case, we should not + // render the leaf, to avoid errors further down the tree. + if ( ! block ) { + return null; + } + + const blockPositionDescription = getBlockPositionDescription( + position, + siblingBlockCount, + level + ); + + const blockAriaLabel = isLocked + ? sprintf( + // translators: %s: The title of the block. This string indicates a link to select the locked block. + __( '%s (locked)' ), + blockTitle + ) + : blockTitle; + + const settingsAriaLabel = sprintf( + // translators: %s: The title of the block. + __( 'Options for %s' ), + blockTitle + ); + + const hasSiblings = siblingBlockCount > 0; + const hasRenderedMovers = showBlockMovers && hasSiblings; + const moverCellClassName = classnames( + 'block-editor-list-view-block__mover-cell', + { 'is-visible': isHovered || isSelected } + ); + + const listViewBlockSettingsClassName = classnames( + 'block-editor-list-view-block__menu-cell', + { 'is-visible': isHovered || isFirstSelectedBlock } + ); + let colSpan; if ( hasRenderedMovers ) { colSpan = 2; @@ -288,15 +305,6 @@ function ListViewBlock( { ? selectedClientIds : [ clientId ]; - // Pass in a ref to the row, so that it can be scrolled - // into view when selected. For long lists, the placeholder for the - // selected block is also observed, within ListViewLeafPlaceholder. - useListViewScrollIntoView( { - isSelected, - rowItemRef: rowRef, - selectedClientIds, - } ); - // Detect if there is a block in the canvas currently being edited and multi-selection is not happening. const currentlyEditingBlockInCanvas = isSelected && selectedClientIds.length === 1;