From 4f72f265065346b6176b63a84012281100d48cee Mon Sep 17 00:00:00 2001 From: Michal Date: Wed, 9 Feb 2022 03:07:46 -0500 Subject: [PATCH] Comment Template: Improve UX of inner block selection (#38263) * Comment Template: Rename firstBlock to firstComment * Comment Template: Fix jumping of elements * Comment template: Fix flicker --- .../src/comment-template/edit.js | 73 +++++++++++++++---- 1 file changed, 59 insertions(+), 14 deletions(-) diff --git a/packages/block-library/src/comment-template/edit.js b/packages/block-library/src/comment-template/edit.js index 1cbb2fa0d98ed0..6c4829f363ff6d 100644 --- a/packages/block-library/src/comment-template/edit.js +++ b/packages/block-library/src/comment-template/edit.js @@ -1,15 +1,15 @@ /** * WordPress dependencies */ -import { useState, useMemo } from '@wordpress/element'; +import { useState, useMemo, memo } from '@wordpress/element'; import { useSelect } from '@wordpress/data'; import { __ } from '@wordpress/i18n'; import { BlockContextProvider, - BlockPreview, useBlockProps, useInnerBlocksProps, store as blockEditorStore, + __experimentalUseBlockPreview as useBlockPreview, } from '@wordpress/block-editor'; import { Spinner } from '@wordpress/components'; import { store as coreStore } from '@wordpress/core-data'; @@ -35,7 +35,7 @@ const TEMPLATE = [ * @param {Array} [props.comment] - A comment object. * @param {Array} [props.activeComment] - The block that is currently active. * @param {Array} [props.setActiveComment] - The setter for activeComment. - * @param {Array} [props.firstBlock] - First comment in the array. + * @param {Array} [props.firstComment] - First comment in the array. * @param {Array} [props.blocks] - Array of blocks returned from * getBlocks() in parent . * @return {WPElement} Inner blocks of the Comment Template @@ -44,7 +44,7 @@ function CommentTemplateInnerBlocks( { comment, activeComment, setActiveComment, - firstBlock, + firstComment, blocks, } ) { const { children, ...innerBlocksProps } = useInnerBlocksProps( @@ -53,15 +53,22 @@ function CommentTemplateInnerBlocks( { ); return (
  • - { comment === ( activeComment || firstBlock ) ? ( - children - ) : ( - setActiveComment( comment ) } - /> - ) } + { comment === ( activeComment || firstComment ) ? children : null } + + { /* To avoid flicker when switching active block contexts, a preview + is ALWAYS rendered and the preview for the active block is hidden. + This ensures that when switching the active block, the component is not + mounted again but rather it only toggles the `isHidden` prop. + + The same strategy is used for preventing the flicker in the Post Template + block. */ } + + { comment?.children?.length > 0 ? ( { + const blockPreviewProps = useBlockPreview( { + blocks, + } ); + + const handleOnClick = () => { + setActiveComment( comment ); + }; + + // We have to hide the preview block if the `comment` props points to + // the curently active block! + + // Or, to put it differently, every preview block is visible unless it is the + // currently active block - in this case we render its inner blocks. + const style = { + display: isHidden ? 'none' : undefined, + }; + + return ( +
    + ); +}; + +const MemoizedCommentTemplatePreview = memo( CommentTemplatePreview ); + /** * Component that renders a list of (nested) comments. It is called recursively. * @@ -105,7 +150,7 @@ const CommentsList = ( { activeComment={ activeComment } setActiveComment={ setActiveComment } blocks={ blocks } - firstBlock={ comments[ 0 ] } + firstComment={ comments[ 0 ] } /> ) ) }