diff --git a/packages/edit-site/src/components/block-editor/block-editor-provider/default-block-editor-provider.js b/packages/edit-site/src/components/block-editor/block-editor-provider/default-block-editor-provider.js index 9ffee1ca68722..a29552edaef22 100644 --- a/packages/edit-site/src/components/block-editor/block-editor-provider/default-block-editor-provider.js +++ b/packages/edit-site/src/components/block-editor/block-editor-provider/default-block-editor-provider.js @@ -51,13 +51,18 @@ export default function DefaultBlockEditorProvider( { children } ) { 'postType', templateType ); - const pageContentBlock = usePageContentBlocks( blocks, isTemplateHidden ); + const pageContentBlocks = usePageContentBlocks( { + blocks, + isPageContentFocused: isTemplateHidden, + wrapPageContent: true, + } ); + return ( { ]; it( 'should return empty array if `isPageContentFocused` is `false`', () => { const { result } = renderHook( () => - usePageContentBlocks( blocksList, false ) + usePageContentBlocks( { + blocks: blocksList, + isPageContentFocused: false, + } ) ); expect( result.current ).toEqual( [] ); } ); it( 'should return empty array if `blocks` is undefined', () => { const { result } = renderHook( () => - usePageContentBlocks( undefined, true ) + usePageContentBlocks( { + blocks: undefined, + isPageContentFocused: true, + } ) ); expect( result.current ).toEqual( [] ); } ); it( 'should return empty array if `blocks` is an empty array', () => { - const { result } = renderHook( () => usePageContentBlocks( [], true ) ); + const { result } = renderHook( () => + usePageContentBlocks( { + blocks: [], + isPageContentFocused: true, + } ) + ); expect( result.current ).toEqual( [] ); } ); it( 'should return new block list', () => { const { result } = renderHook( () => - usePageContentBlocks( blocksList, true ) + usePageContentBlocks( { + blocks: blocksList, + isPageContentFocused: true, + } ) + ); + expect( result.current ).toEqual( [ + createBlock( 'core/post-title' ), + createBlock( 'core/post-featured-image' ), + createBlock( 'core/post-content' ), + createBlock( 'core/post-content' ), + ] ); + } ); + it( 'should return new block list wrapped in a Group block', () => { + const { result } = renderHook( () => + usePageContentBlocks( { + blocks: blocksList, + isPageContentFocused: true, + wrapPageContent: true, + } ) ); expect( result.current ).toEqual( [ { diff --git a/packages/edit-site/src/components/block-editor/block-editor-provider/use-page-content-blocks.js b/packages/edit-site/src/components/block-editor/block-editor-provider/use-page-content-blocks.js index 17e907113c515..dd05f90a56bbb 100644 --- a/packages/edit-site/src/components/block-editor/block-editor-provider/use-page-content-blocks.js +++ b/packages/edit-site/src/components/block-editor/block-editor-provider/use-page-content-blocks.js @@ -38,21 +38,38 @@ function flattenBlocks( blocks, transform ) { /** * Returns a memoized array of blocks that contain only page content blocks, - * surrounded by a group block to mimic the post editor. - * - * @param {Array} blocks Block list. - * @param {boolean} isPageContentFocused Whether the page content has focus. If `true` return page content blocks. Default `false`. + * surrounded by an optional group block to mimic the post editor. * + * @param {Object} props The argument for the function. + * @param {Array} props.blocks Block list. + * @param {boolean} props.isPageContentFocused Whether the page content has focus (and the surrounding template is inert). If `true` return page content blocks. Default `false`. + * @param {boolean} props.wrapPageContent Whether to wrap the page content blocks in a group block to mimic the post editor. Default `false`. * @return {Array} Page content blocks. */ -export default function usePageContentBlocks( - blocks, - isPageContentFocused = false -) { +export default function usePageContentBlocks( { + blocks = [], + isPageContentFocused = false, + wrapPageContent = false, +} ) { return useMemo( () => { - if ( ! isPageContentFocused || ! blocks || ! blocks.length ) { + if ( ! isPageContentFocused || ! blocks?.length ) { + return []; + } + + const innerBlocks = flattenBlocks( blocks, ( block ) => + PAGE_CONTENT_BLOCK_TYPES[ block.name ] + ? createBlock( block.name ) + : undefined + ); + + if ( ! innerBlocks.length ) { return []; } + + if ( ! wrapPageContent ) { + return innerBlocks; + } + return [ createBlock( 'core/group', @@ -66,11 +83,7 @@ export default function usePageContentBlocks( }, }, }, - flattenBlocks( blocks, ( block ) => { - if ( PAGE_CONTENT_BLOCK_TYPES[ block.name ] ) { - return createBlock( block.name ); - } - } ) + innerBlocks ), ]; }, [ blocks, isPageContentFocused ] ); diff --git a/packages/edit-site/src/components/page-content-focus-manager/index.js b/packages/edit-site/src/components/page-content-focus-manager/index.js index 935ba1c96248c..05bcc0da003cf 100644 --- a/packages/edit-site/src/components/page-content-focus-manager/index.js +++ b/packages/edit-site/src/components/page-content-focus-manager/index.js @@ -1,8 +1,8 @@ /** * WordPress dependencies */ -import { useSelect } from '@wordpress/data'; - +import { useSelect, useDispatch } from '@wordpress/data'; +import { useEffect } from '@wordpress/element'; /** * Internal dependencies */ @@ -10,12 +10,37 @@ import { store as editSiteStore } from '../../store'; import DisableNonPageContentBlocks from './disable-non-page-content-blocks'; import EditTemplateNotification from './edit-template-notification'; import BackToPageNotification from './back-to-page-notification'; +import { unlock } from '../../lock-unlock'; export default function PageContentFocusManager( { contentRef } ) { - const hasPageContentFocus = useSelect( - ( select ) => select( editSiteStore ).hasPageContentFocus(), + const { hasPageContentFocus, pageContentFocusType, canvasMode } = useSelect( + ( select ) => { + const { getPageContentFocusType, getCanvasMode } = unlock( + select( editSiteStore ) + ); + const _canvasMode = getCanvasMode(); + return { + canvasMode: _canvasMode, + pageContentFocusType: getPageContentFocusType(), + hasPageContentFocus: + select( editSiteStore ).hasPageContentFocus(), + }; + }, [] ); + const { setPageContentFocusType } = unlock( useDispatch( editSiteStore ) ); + + /* + * Ensure that the page content focus type is set to `disableTemplate` when + * the canvas mode is not `edit`. This makes the experience consistent with + * refreshing the page, which resets the page content focus type. + */ + useEffect( () => { + if ( canvasMode !== 'edit' && !! pageContentFocusType ) { + setPageContentFocusType( null ); + } + }, [ canvasMode, pageContentFocusType ] ); + return ( <> { hasPageContentFocus && } diff --git a/packages/edit-site/src/components/sidebar-edit-mode/page-panels/edit-template.js b/packages/edit-site/src/components/sidebar-edit-mode/page-panels/edit-template.js index 9e0b9e37c33ff..8067453a51821 100644 --- a/packages/edit-site/src/components/sidebar-edit-mode/page-panels/edit-template.js +++ b/packages/edit-site/src/components/sidebar-edit-mode/page-panels/edit-template.js @@ -11,7 +11,7 @@ import { __experimentalText as Text, } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; -import { store as coreStore } from '@wordpress/core-data'; +import { store as coreStore, useEntityBlockEditor } from '@wordpress/core-data'; import { check } from '@wordpress/icons'; /** @@ -21,6 +21,7 @@ import { store as editSiteStore } from '../../../store'; import SwapTemplateButton from './swap-template-button'; import ResetDefaultTemplate from './reset-default-template'; import { unlock } from '../../../lock-unlock'; +import usePageContentBlocks from '../../block-editor/block-editor-provider/use-page-content-blocks'; const POPOVER_PROPS = { className: 'edit-site-page-panels-edit-template__dropdown', @@ -28,7 +29,7 @@ const POPOVER_PROPS = { }; export default function EditTemplate() { - const { hasResolved, template, isTemplateHidden } = useSelect( + const { hasResolved, template, isTemplateHidden, postType } = useSelect( ( select ) => { const { getEditedPostContext, getEditedPostType, getEditedPostId } = select( editSiteStore ); @@ -38,11 +39,13 @@ export default function EditTemplate() { const { getEditedEntityRecord, hasFinishedResolution } = select( coreStore ); const _context = getEditedPostContext(); + const _postType = getEditedPostType(); const queryArgs = [ 'postType', getEditedPostType(), getEditedPostId(), ]; + return { context: _context, hasResolved: hasFinishedResolution( @@ -53,15 +56,23 @@ export default function EditTemplate() { isTemplateHidden: getCanvasMode() === 'edit' && getPageContentFocusType() === 'hideTemplate', + postType: _postType, }; }, [] ); + const [ blocks ] = useEntityBlockEditor( 'postType', postType ); + const { setHasPageContentFocus } = useDispatch( editSiteStore ); // Disable reason: `useDispatch` can't be called conditionally. // eslint-disable-next-line @wordpress/no-unused-vars-before-return const { setPageContentFocusType } = unlock( useDispatch( editSiteStore ) ); + // Check if there are any post content block types in the blocks tree. + const pageContentBlocks = usePageContentBlocks( { + blocks, + isPageContentFocused: true, + } ); if ( ! hasResolved ) { return null; @@ -97,20 +108,24 @@ export default function EditTemplate() { - - { - setPageContentFocusType( - isTemplateHidden - ? 'disableTemplate' - : 'hideTemplate' - ); - } } - > - { __( 'Template preview' ) } - - + { !! pageContentBlocks?.length && ( + + { + setPageContentFocusType( + isTemplateHidden + ? 'disableTemplate' + : 'hideTemplate' + ); + } } + > + { __( 'Template preview' ) } + + + ) } ) }