From 045df9ebdd275cf3ccf23566f2e38683be195c73 Mon Sep 17 00:00:00 2001 From: Robert Anderson Date: Fri, 9 Jun 2023 17:07:43 +1000 Subject: [PATCH 01/10] Improve guidance to editing template when focused on editing a page --- packages/block-editor/src/store/selectors.js | 2 +- .../src/components/block-editor/index.js | 41 +++--- .../back-to-page-notification.js | 65 +++++++++ .../constants.js | 0 .../disable-non-page-content-blocks.js | 2 +- .../edit-template-dialog.js | 52 +++++++ .../edit-template-notification.js | 74 ++++++++++ .../page-content-focus-manager/index.js | 34 +++++ .../page-content-flash.js | 59 ++++++++ .../components/page-content-focus/index.js | 2 - .../use-page-content-focus-notifications.js | 128 ------------------ .../page-panels/page-content.js | 2 +- 12 files changed, 303 insertions(+), 158 deletions(-) create mode 100644 packages/edit-site/src/components/page-content-focus-manager/back-to-page-notification.js rename packages/edit-site/src/components/{page-content-focus => page-content-focus-manager}/constants.js (100%) rename packages/edit-site/src/components/{page-content-focus => page-content-focus-manager}/disable-non-page-content-blocks.js (96%) create mode 100644 packages/edit-site/src/components/page-content-focus-manager/edit-template-dialog.js create mode 100644 packages/edit-site/src/components/page-content-focus-manager/edit-template-notification.js create mode 100644 packages/edit-site/src/components/page-content-focus-manager/index.js create mode 100644 packages/edit-site/src/components/page-content-focus-manager/page-content-flash.js delete mode 100644 packages/edit-site/src/components/page-content-focus/index.js delete mode 100644 packages/edit-site/src/components/page-content-focus/use-page-content-focus-notifications.js diff --git a/packages/block-editor/src/store/selectors.js b/packages/block-editor/src/store/selectors.js index 10bf42ec230945..77c4f402df9f0f 100644 --- a/packages/block-editor/src/store/selectors.js +++ b/packages/block-editor/src/store/selectors.js @@ -2822,7 +2822,7 @@ export function __unstableHasActiveBlockOverlayActive( state, clientId ) { // Prevent overlay on disabled blocks. It's redundant since disabled blocks // can't be selected, and prevents non-disabled nested blocks from being // selected. - if ( getBlockEditingMode( state, clientId ) === 'disabled' ) { + if ( getBlockEditingMode( state, clientId ) !== 'default' ) { return false; } diff --git a/packages/edit-site/src/components/block-editor/index.js b/packages/edit-site/src/components/block-editor/index.js index 71f1ee93097e28..a2418f724b67f7 100644 --- a/packages/edit-site/src/components/block-editor/index.js +++ b/packages/edit-site/src/components/block-editor/index.js @@ -38,10 +38,7 @@ import ResizableEditor from './resizable-editor'; import EditorCanvas from './editor-canvas'; import { unlock } from '../../lock-unlock'; import EditorCanvasContainer from '../editor-canvas-container'; -import { - DisableNonPageContentBlocks, - usePageContentFocusNotifications, -} from '../page-content-focus'; +import PageContentFocusManager from '../page-content-focus-manager'; const { ExperimentalBlockEditorProvider } = unlock( blockEditorPrivateApis ); @@ -53,25 +50,20 @@ const LAYOUT = { export default function BlockEditor() { const { setIsInserterOpened } = useDispatch( editSiteStore ); - const { storedSettings, templateType, canvasMode, hasPageContentFocus } = - useSelect( - ( select ) => { - const { - getSettings, - getEditedPostType, - getCanvasMode, - hasPageContentFocus: _hasPageContentFocus, - } = unlock( select( editSiteStore ) ); - - return { - storedSettings: getSettings( setIsInserterOpened ), - templateType: getEditedPostType(), - canvasMode: getCanvasMode(), - hasPageContentFocus: _hasPageContentFocus(), - }; - }, - [ setIsInserterOpened ] - ); + const { storedSettings, templateType, canvasMode } = useSelect( + ( select ) => { + const { getSettings, getEditedPostType, getCanvasMode } = unlock( + select( editSiteStore ) + ); + + return { + storedSettings: getSettings( setIsInserterOpened ), + templateType: getEditedPostType(), + canvasMode: getCanvasMode(), + }; + }, + [ setIsInserterOpened ] + ); const settingsBlockPatterns = storedSettings.__experimentalAdditionalBlockPatterns ?? // WP 6.0 @@ -146,7 +138,6 @@ export default function BlockEditor() { contentRef, useClipboardHandler(), useTypingObserver(), - usePageContentFocusNotifications(), ] ); const isMobileViewport = useViewportMatch( 'small', '<' ); const { clearSelectedBlock } = useDispatch( blockEditorStore ); @@ -172,7 +163,7 @@ export default function BlockEditor() { onChange={ onChange } useSubRegistry={ false } > - { hasPageContentFocus && } + diff --git a/packages/edit-site/src/components/page-content-focus-manager/back-to-page-notification.js b/packages/edit-site/src/components/page-content-focus-manager/back-to-page-notification.js new file mode 100644 index 00000000000000..2eb882cdbf847b --- /dev/null +++ b/packages/edit-site/src/components/page-content-focus-manager/back-to-page-notification.js @@ -0,0 +1,65 @@ +/** + * WordPress dependencies + */ +import { useSelect, useDispatch } from '@wordpress/data'; +import { useEffect, useRef } from '@wordpress/element'; +import { store as noticesStore } from '@wordpress/notices'; +import { __ } from '@wordpress/i18n'; + +/** + * Internal dependencies + */ +import { store as editSiteStore } from '../../store'; + +/** + * Component that displays a 'You are editing a template' notification when the + * user switches from focusing on editing page content to editing a template. + */ +export default function BackToPageNotification() { + useBackToPageNotification(); + return null; +} + +/** + * Hook that displays a 'You are editing a template' notification when the user + * switches from focusing on editing page content to editing a template. + */ +export function useBackToPageNotification() { + const hasPageContentFocus = useSelect( + ( select ) => select( editSiteStore ).hasPageContentFocus(), + [] + ); + + const alreadySeen = useRef( false ); + const prevHasPageContentFocus = useRef( false ); + + const { createInfoNotice } = useDispatch( noticesStore ); + const { setHasPageContentFocus } = useDispatch( editSiteStore ); + + useEffect( () => { + if ( + ! alreadySeen.current && + prevHasPageContentFocus.current && + ! hasPageContentFocus + ) { + createInfoNotice( __( 'You are editing a template' ), { + isDismissible: true, + type: 'snackbar', + actions: [ + { + label: __( 'Back to page' ), + onClick: () => setHasPageContentFocus( true ), + }, + ], + } ); + alreadySeen.current = true; + } + prevHasPageContentFocus.current = hasPageContentFocus; + }, [ + alreadySeen, + prevHasPageContentFocus, + hasPageContentFocus, + createInfoNotice, + setHasPageContentFocus, + ] ); +} diff --git a/packages/edit-site/src/components/page-content-focus/constants.js b/packages/edit-site/src/components/page-content-focus-manager/constants.js similarity index 100% rename from packages/edit-site/src/components/page-content-focus/constants.js rename to packages/edit-site/src/components/page-content-focus-manager/constants.js diff --git a/packages/edit-site/src/components/page-content-focus/disable-non-page-content-blocks.js b/packages/edit-site/src/components/page-content-focus-manager/disable-non-page-content-blocks.js similarity index 96% rename from packages/edit-site/src/components/page-content-focus/disable-non-page-content-blocks.js rename to packages/edit-site/src/components/page-content-focus-manager/disable-non-page-content-blocks.js index 9bd86fb1b4e246..33ea486863d203 100644 --- a/packages/edit-site/src/components/page-content-focus/disable-non-page-content-blocks.js +++ b/packages/edit-site/src/components/page-content-focus-manager/disable-non-page-content-blocks.js @@ -18,7 +18,7 @@ const { useBlockEditingMode } = unlock( blockEditorPrivateApis ); * Component that when rendered, makes it so that the site editor allows only * page content to be edited. */ -export function DisableNonPageContentBlocks() { +export default function DisableNonPageContentBlocks() { useDisableNonPageContentBlocks(); } diff --git a/packages/edit-site/src/components/page-content-focus-manager/edit-template-dialog.js b/packages/edit-site/src/components/page-content-focus-manager/edit-template-dialog.js new file mode 100644 index 00000000000000..0e31aa549f1c99 --- /dev/null +++ b/packages/edit-site/src/components/page-content-focus-manager/edit-template-dialog.js @@ -0,0 +1,52 @@ +/** + * WordPress dependencies + */ +import { useDispatch } from '@wordpress/data'; +import { useEffect, useState } from '@wordpress/element'; +import { __ } from '@wordpress/i18n'; +import { __experimentalConfirmDialog as ConfirmDialog } from '@wordpress/components'; + +/** + * Internal dependencies + */ +import { store as editSiteStore } from '../../store'; + +/** + * Component that displays a 'Edit your template to edit this block' + * notification when the user is focusing on editing page content and clicks on + * a disabled template block. + * + * @param {Object} props + * @param {import('react').RefObject} props.contentRef Ref to the block + * editor iframe canvas. + */ +export default function EditTemplateDialog( { contentRef } ) { + const [ isOpen, setIsOpen ] = useState( false ); + + useEffect( () => { + const handleDblClick = ( event ) => { + if ( event.target.classList.contains( 'is-root-container' ) ) { + setIsOpen( true ); + } + }; + const canvas = contentRef.current; + canvas?.addEventListener( 'dblclick', handleDblClick ); + return () => canvas?.removeEventListener( 'dblclick', handleDblClick ); + }, [ contentRef.current ] ); + + const { setHasPageContentFocus } = useDispatch( editSiteStore ); + + return ( + { + setIsOpen( false ); + setHasPageContentFocus( false ); + } } + onCancel={ () => setIsOpen( false ) } + > + { __( 'Edit your template to edit this block' ) } + + ); +} diff --git a/packages/edit-site/src/components/page-content-focus-manager/edit-template-notification.js b/packages/edit-site/src/components/page-content-focus-manager/edit-template-notification.js new file mode 100644 index 00000000000000..124f3eb1d4ef7c --- /dev/null +++ b/packages/edit-site/src/components/page-content-focus-manager/edit-template-notification.js @@ -0,0 +1,74 @@ +/** + * WordPress dependencies + */ +import { useSelect, useDispatch } from '@wordpress/data'; +import { useEffect, useRef } from '@wordpress/element'; +import { store as noticesStore } from '@wordpress/notices'; +import { __ } from '@wordpress/i18n'; + +/** + * Internal dependencies + */ +import { store as editSiteStore } from '../../store'; + +/** + * Component that displays a 'Edit your template to edit this block' + * notification when the user is focusing on editing page content and clicks on + * a disabled template block. + * + * @param {Object} props + * @param {import('react').RefObject} props.contentRef Ref to the block + * editor iframe canvas. + */ +export default function EditTemplateNotification( { contentRef } ) { + useEditTemplateNotification( contentRef ); + return null; +} + +/** + * Hook that displays a 'Edit your template to edit this block' notification + * when the user is focusing on editing page content and clicks on a disabled + * template block. + * + * @param {import('react').RefObject} contentRef Ref to the block + * editor iframe canvas. + */ +function useEditTemplateNotification( contentRef ) { + const hasPageContentFocus = useSelect( + ( select ) => select( editSiteStore ).hasPageContentFocus(), + [] + ); + + const alreadySeen = useRef( false ); + + const { createInfoNotice } = useDispatch( noticesStore ); + const { setHasPageContentFocus } = useDispatch( editSiteStore ); + + useEffect( () => { + const handleClick = ( event ) => { + if ( + ! alreadySeen.current && + hasPageContentFocus && + event.target.classList.contains( 'is-root-container' ) + ) { + createInfoNotice( + __( 'Edit your template to edit this block' ), + { + isDismissible: true, + type: 'snackbar', + actions: [ + { + label: __( 'Edit template' ), + onClick: () => setHasPageContentFocus( false ), + }, + ], + } + ); + alreadySeen.current = true; + } + }; + const canvas = contentRef.current; + canvas?.addEventListener( 'click', handleClick ); + return () => canvas?.removeEventListener( 'click', handleClick ); + }, [ alreadySeen, hasPageContentFocus, contentRef.current ] ); +} 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 new file mode 100644 index 00000000000000..5545daaacc7758 --- /dev/null +++ b/packages/edit-site/src/components/page-content-focus-manager/index.js @@ -0,0 +1,34 @@ +/** + * WordPress dependencies + */ +import { useSelect } from '@wordpress/data'; + +/** + * Internal dependencies + */ +import { store as editSiteStore } from '../../store'; +import DisableNonPageContentBlocks from './disable-non-page-content-blocks'; +import EditTemplateDialog from './edit-template-dialog'; +import PageContentFlash from './page-content-flash'; +import EditTemplateNotification from './edit-template-notification'; +import BackToPageNotification from './back-to-page-notification'; + +export default function PageContentFocusManager( { contentRef } ) { + const hasPageContentFocus = useSelect( + ( select ) => select( editSiteStore ).hasPageContentFocus(), + [] + ); + return ( + <> + { hasPageContentFocus && ( + <> + + + + + ) } + + + + ); +} diff --git a/packages/edit-site/src/components/page-content-focus-manager/page-content-flash.js b/packages/edit-site/src/components/page-content-focus-manager/page-content-flash.js new file mode 100644 index 00000000000000..092d617d7d6c4a --- /dev/null +++ b/packages/edit-site/src/components/page-content-focus-manager/page-content-flash.js @@ -0,0 +1,59 @@ +/** + * WordPress dependencies + */ +import { useEffect } from '@wordpress/element'; +// import { useSelect, useDispatch } from '@wordpress/data'; +// import { store as blockEditorStore } from '@wordpress/block-editor'; + +/** + * Internal dependencies + */ +import { PAGE_CONTENT_BLOCK_TYPES } from './constants'; + +export default function PageContentFlash( { contentRef } ) { + usePageContentFlash( contentRef ); + return null; +} + +export function usePageContentFlash( contentRef ) { + // const { __experimentalGetGlobalBlocksByName } = + // useSelect( blockEditorStore ); + + // const { flashBlock } = useDispatch( blockEditorStore ); + + useEffect( () => { + const canvas = contentRef.current; + if ( ! canvas ) { + return; + } + const handleClick = ( event ) => { + if ( event.target.classList.contains( 'is-root-container' ) ) { + // const clientIds = __experimentalGetGlobalBlocksByName( + // PAGE_CONTENT_BLOCK_TYPES + // ); + // for ( const clientId of clientIds ) { + // flashBlock( clientId ); + // } + canvas + .querySelectorAll( + PAGE_CONTENT_BLOCK_TYPES.map( + ( blockType ) => `[data-type="${ blockType }"]` + ).join( ',' ) + // '.block-editor-block-list__block:not(.is-editing-disabled)' + ) + .forEach( ( block ) => { + const flash = async () => { + block.classList.add( 'is-highlighted' ); + await new Promise( ( resolve ) => + setTimeout( resolve, 150 ) + ); + block.classList.remove( 'is-highlighted' ); + }; + flash(); + } ); + } + }; + canvas.addEventListener( 'click', handleClick ); + return () => canvas.removeEventListener( 'click', handleClick ); + }, [ contentRef.current ] ); +} diff --git a/packages/edit-site/src/components/page-content-focus/index.js b/packages/edit-site/src/components/page-content-focus/index.js deleted file mode 100644 index 81160f4a861f93..00000000000000 --- a/packages/edit-site/src/components/page-content-focus/index.js +++ /dev/null @@ -1,2 +0,0 @@ -export * from './disable-non-page-content-blocks'; -export { usePageContentFocusNotifications } from './use-page-content-focus-notifications'; diff --git a/packages/edit-site/src/components/page-content-focus/use-page-content-focus-notifications.js b/packages/edit-site/src/components/page-content-focus/use-page-content-focus-notifications.js deleted file mode 100644 index a1ebc729294d53..00000000000000 --- a/packages/edit-site/src/components/page-content-focus/use-page-content-focus-notifications.js +++ /dev/null @@ -1,128 +0,0 @@ -/** - * WordPress dependencies - */ -import { useSelect, useDispatch } from '@wordpress/data'; -import { useEffect, useRef } from '@wordpress/element'; -import { store as noticesStore } from '@wordpress/notices'; -import { __ } from '@wordpress/i18n'; -import { useRefEffect } from '@wordpress/compose'; - -/** - * Internal dependencies - */ -import { store as editSiteStore } from '../../store'; - -/** - * Hook that displays notifications that guide the user towards using the - * content vs. template editing modes. - * - * @return {import('react').RefObject} Ref which should be passed - * (using useMergeRefs()) to - * the editor iframe canvas. - */ -export function usePageContentFocusNotifications() { - const ref = useEditTemplateNotification(); - useBackToPageNotification(); - return ref; -} - -/** - * Hook that displays a 'Edit your template to edit this block' notification - * when the user is focusing on editing page content and clicks on a disabled - * template block. - * - * @return {import('react').RefObject} Ref which should be passed - * (using useMergeRefs()) to - * the editor iframe canvas. - */ -function useEditTemplateNotification() { - const hasPageContentFocus = useSelect( - ( select ) => select( editSiteStore ).hasPageContentFocus(), - [] - ); - - const alreadySeen = useRef( false ); - - const { createInfoNotice } = useDispatch( noticesStore ); - const { setHasPageContentFocus } = useDispatch( editSiteStore ); - - return useRefEffect( - ( node ) => { - const handleClick = ( event ) => { - if ( - ! alreadySeen.current && - hasPageContentFocus && - event.target.classList.contains( 'is-root-container' ) - ) { - createInfoNotice( - __( 'Edit your template to edit this block' ), - { - isDismissible: true, - type: 'snackbar', - actions: [ - { - label: __( 'Edit template' ), - onClick: () => - setHasPageContentFocus( false ), - }, - ], - } - ); - alreadySeen.current = true; - } - }; - node.addEventListener( 'click', handleClick ); - return () => node.removeEventListener( 'click', handleClick ); - }, - [ - hasPageContentFocus, - alreadySeen, - createInfoNotice, - setHasPageContentFocus, - ] - ); -} - -/** - * Hook that displays a 'You are editing a template' notification when the user - * switches from focusing on editing page content to editing a template. - */ -function useBackToPageNotification() { - const hasPageContentFocus = useSelect( - ( select ) => select( editSiteStore ).hasPageContentFocus(), - [] - ); - - const alreadySeen = useRef( false ); - const prevHasPageContentFocus = useRef( false ); - - const { createInfoNotice } = useDispatch( noticesStore ); - const { setHasPageContentFocus } = useDispatch( editSiteStore ); - - useEffect( () => { - if ( - ! alreadySeen.current && - prevHasPageContentFocus.current && - ! hasPageContentFocus - ) { - createInfoNotice( __( 'You are editing a template' ), { - isDismissible: true, - type: 'snackbar', - actions: [ - { - label: __( 'Back to page' ), - onClick: () => setHasPageContentFocus( true ), - }, - ], - } ); - alreadySeen.current = true; - } - prevHasPageContentFocus.current = hasPageContentFocus; - }, [ - alreadySeen, - prevHasPageContentFocus, - hasPageContentFocus, - createInfoNotice, - setHasPageContentFocus, - ] ); -} diff --git a/packages/edit-site/src/components/sidebar-edit-mode/page-panels/page-content.js b/packages/edit-site/src/components/sidebar-edit-mode/page-panels/page-content.js index 301f898d794a4b..d6e7dd23a709fa 100644 --- a/packages/edit-site/src/components/sidebar-edit-mode/page-panels/page-content.js +++ b/packages/edit-site/src/components/sidebar-edit-mode/page-panels/page-content.js @@ -10,7 +10,7 @@ import { /** * Internal dependencies */ -import { PAGE_CONTENT_BLOCK_TYPES } from '../../page-content-focus/constants'; +import { PAGE_CONTENT_BLOCK_TYPES } from '../../page-content-focus-manager/constants'; import { unlock } from '../../../lock-unlock'; const { BlockQuickNavigation } = unlock( blockEditorPrivateApis ); From 11fb8889c2115bb53db6544388298edf7acb2f13 Mon Sep 17 00:00:00 2001 From: Robert Anderson Date: Tue, 13 Jun 2023 10:51:02 +1000 Subject: [PATCH 02/10] Don't flash content blocks when double clicking --- .../page-content-flash.js | 64 ++++++++++++------- 1 file changed, 40 insertions(+), 24 deletions(-) diff --git a/packages/edit-site/src/components/page-content-focus-manager/page-content-flash.js b/packages/edit-site/src/components/page-content-focus-manager/page-content-flash.js index 092d617d7d6c4a..b5f8e8ec3842c0 100644 --- a/packages/edit-site/src/components/page-content-focus-manager/page-content-flash.js +++ b/packages/edit-site/src/components/page-content-focus-manager/page-content-flash.js @@ -26,34 +26,50 @@ export function usePageContentFlash( contentRef ) { if ( ! canvas ) { return; } + const flashContentBlocks = () => { + // const clientIds = __experimentalGetGlobalBlocksByName( + // PAGE_CONTENT_BLOCK_TYPES + // ); + // for ( const clientId of clientIds ) { + // flashBlock( clientId ); + // } + canvas + .querySelectorAll( + PAGE_CONTENT_BLOCK_TYPES.map( + ( blockType ) => `[data-type="${ blockType }"]` + ).join( ',' ) + // '.block-editor-block-list__block:not(.is-editing-disabled)' + ) + .forEach( ( block ) => { + const flash = async () => { + block.classList.add( 'is-highlighted' ); + await new Promise( ( resolve ) => + setTimeout( resolve, 150 ) + ); + block.classList.remove( 'is-highlighted' ); + }; + flash(); + } ); + }; + let timeout; const handleClick = ( event ) => { + if ( + event.target.classList.contains( 'is-root-container' ) && + event.detail === 1 + ) { + timeout = setTimeout( flashContentBlocks, 300 ); + } + }; + const handleDblClick = ( event ) => { if ( event.target.classList.contains( 'is-root-container' ) ) { - // const clientIds = __experimentalGetGlobalBlocksByName( - // PAGE_CONTENT_BLOCK_TYPES - // ); - // for ( const clientId of clientIds ) { - // flashBlock( clientId ); - // } - canvas - .querySelectorAll( - PAGE_CONTENT_BLOCK_TYPES.map( - ( blockType ) => `[data-type="${ blockType }"]` - ).join( ',' ) - // '.block-editor-block-list__block:not(.is-editing-disabled)' - ) - .forEach( ( block ) => { - const flash = async () => { - block.classList.add( 'is-highlighted' ); - await new Promise( ( resolve ) => - setTimeout( resolve, 150 ) - ); - block.classList.remove( 'is-highlighted' ); - }; - flash(); - } ); + clearTimeout( timeout ); } }; canvas.addEventListener( 'click', handleClick ); - return () => canvas.removeEventListener( 'click', handleClick ); + canvas.addEventListener( 'dblclick', handleDblClick ); + return () => { + canvas.removeEventListener( 'click', handleClick ); + canvas.removeEventListener( 'dblclick', handleDblClick ); + }; }, [ contentRef.current ] ); } From 2f9cf3c879e27bd352d42fc8ac58bfce533051cd Mon Sep 17 00:00:00 2001 From: Robert Anderson Date: Tue, 13 Jun 2023 11:15:52 +1000 Subject: [PATCH 03/10] Use flashBlock() --- .../src/components/block-list/content.scss | 5 +++ packages/block-editor/src/store/reducer.js | 45 +++++++++++-------- packages/block-editor/src/store/selectors.js | 2 +- .../page-content-flash.js | 39 +++++----------- 4 files changed, 44 insertions(+), 47 deletions(-) diff --git a/packages/block-editor/src/components/block-list/content.scss b/packages/block-editor/src/components/block-list/content.scss index a163ddaa789551..783d48bfcc844d 100644 --- a/packages/block-editor/src/components/block-list/content.scss +++ b/packages/block-editor/src/components/block-list/content.scss @@ -108,6 +108,11 @@ .is-dark-theme & { box-shadow: 0 0 0 var(--wp-admin-border-width-focus) $dark-theme-focus; } + + transition: + border-color 0.1s linear, + border-style 0.1s linear, + box-shadow 0.1s linear; } } diff --git a/packages/block-editor/src/store/reducer.js b/packages/block-editor/src/store/reducer.js index b851c0293c8f16..7fa976f78e7bf7 100644 --- a/packages/block-editor/src/store/reducer.js +++ b/packages/block-editor/src/store/reducer.js @@ -1759,29 +1759,38 @@ export function lastBlockAttributesChange( state = null, action ) { } /** - * Reducer returning current highlighted block. + * Reducer returning map of block client IDs to whether or not they are + * highlighted. * - * @param {boolean} state Current highlighted block. - * @param {Object} action Dispatched action. + * @param {Object} state Current state. + * @param {Object} action Dispatched action. * - * @return {string} Updated state. + * @return {Object} Updated state. */ -export function highlightedBlock( state, action ) { +export function highlightedBlocks( state = {}, action ) { switch ( action.type ) { - case 'TOGGLE_BLOCK_HIGHLIGHT': - const { clientId, isHighlighted } = action; - - if ( isHighlighted ) { - return clientId; - } else if ( state === clientId ) { - return null; + case 'TOGGLE_BLOCK_HIGHLIGHT': { + if ( action.isHighlighted ) { + if ( ! state[ action.clientId ] ) { + return { + ...state, + [ action.clientId ]: true, + }; + } + } else if ( state[ action.clientId ] ) { + const nextState = { ...state }; + delete nextState[ action.clientId ]; + return nextState; } - - return state; - case 'SELECT_BLOCK': - if ( action.clientId !== state ) { - return null; + break; + } + case 'SELECT_BLOCK': { + if ( state[ action.clientId ] ) { + const nextState = { ...state }; + delete nextState[ action.clientId ]; + return nextState; } + } } return state; @@ -1876,7 +1885,7 @@ const combinedReducers = combineReducers( { lastBlockAttributesChange, editorMode, hasBlockMovingClientId, - highlightedBlock, + highlightedBlocks, lastBlockInserted, temporarilyEditingAsBlocks, blockVisibility, diff --git a/packages/block-editor/src/store/selectors.js b/packages/block-editor/src/store/selectors.js index 77c4f402df9f0f..53037fd2d6d51a 100644 --- a/packages/block-editor/src/store/selectors.js +++ b/packages/block-editor/src/store/selectors.js @@ -2676,7 +2676,7 @@ export function didAutomaticChange( state ) { * @return {boolean} Whether the block is currently highlighted. */ export function isBlockHighlighted( state, clientId ) { - return state.highlightedBlock === clientId; + return !! state.highlightedBlocks[ clientId ]; } /** diff --git a/packages/edit-site/src/components/page-content-focus-manager/page-content-flash.js b/packages/edit-site/src/components/page-content-focus-manager/page-content-flash.js index b5f8e8ec3842c0..3aa0c05d89c1f1 100644 --- a/packages/edit-site/src/components/page-content-focus-manager/page-content-flash.js +++ b/packages/edit-site/src/components/page-content-focus-manager/page-content-flash.js @@ -2,8 +2,8 @@ * WordPress dependencies */ import { useEffect } from '@wordpress/element'; -// import { useSelect, useDispatch } from '@wordpress/data'; -// import { store as blockEditorStore } from '@wordpress/block-editor'; +import { useSelect, useDispatch } from '@wordpress/data'; +import { store as blockEditorStore } from '@wordpress/block-editor'; /** * Internal dependencies @@ -16,10 +16,10 @@ export default function PageContentFlash( { contentRef } ) { } export function usePageContentFlash( contentRef ) { - // const { __experimentalGetGlobalBlocksByName } = - // useSelect( blockEditorStore ); + const { __experimentalGetGlobalBlocksByName } = + useSelect( blockEditorStore ); - // const { flashBlock } = useDispatch( blockEditorStore ); + const { flashBlock } = useDispatch( blockEditorStore ); useEffect( () => { const canvas = contentRef.current; @@ -27,29 +27,12 @@ export function usePageContentFlash( contentRef ) { return; } const flashContentBlocks = () => { - // const clientIds = __experimentalGetGlobalBlocksByName( - // PAGE_CONTENT_BLOCK_TYPES - // ); - // for ( const clientId of clientIds ) { - // flashBlock( clientId ); - // } - canvas - .querySelectorAll( - PAGE_CONTENT_BLOCK_TYPES.map( - ( blockType ) => `[data-type="${ blockType }"]` - ).join( ',' ) - // '.block-editor-block-list__block:not(.is-editing-disabled)' - ) - .forEach( ( block ) => { - const flash = async () => { - block.classList.add( 'is-highlighted' ); - await new Promise( ( resolve ) => - setTimeout( resolve, 150 ) - ); - block.classList.remove( 'is-highlighted' ); - }; - flash(); - } ); + const clientIds = __experimentalGetGlobalBlocksByName( + PAGE_CONTENT_BLOCK_TYPES + ); + for ( const clientId of clientIds ) { + flashBlock( clientId ); + } }; let timeout; const handleClick = ( event ) => { From b5490df0a64e1c9ae9086fd81bb22f0646145736 Mon Sep 17 00:00:00 2001 From: Robert Anderson Date: Wed, 14 Jun 2023 11:05:09 +1000 Subject: [PATCH 04/10] Remove content block flashing for now --- .../page-content-focus-manager/index.js | 2 - .../page-content-flash.js | 58 ------------------- 2 files changed, 60 deletions(-) delete mode 100644 packages/edit-site/src/components/page-content-focus-manager/page-content-flash.js 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 5545daaacc7758..0767be05cc8435 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 @@ -9,7 +9,6 @@ import { useSelect } from '@wordpress/data'; import { store as editSiteStore } from '../../store'; import DisableNonPageContentBlocks from './disable-non-page-content-blocks'; import EditTemplateDialog from './edit-template-dialog'; -import PageContentFlash from './page-content-flash'; import EditTemplateNotification from './edit-template-notification'; import BackToPageNotification from './back-to-page-notification'; @@ -24,7 +23,6 @@ export default function PageContentFocusManager( { contentRef } ) { <> - ) } diff --git a/packages/edit-site/src/components/page-content-focus-manager/page-content-flash.js b/packages/edit-site/src/components/page-content-focus-manager/page-content-flash.js deleted file mode 100644 index 3aa0c05d89c1f1..00000000000000 --- a/packages/edit-site/src/components/page-content-focus-manager/page-content-flash.js +++ /dev/null @@ -1,58 +0,0 @@ -/** - * WordPress dependencies - */ -import { useEffect } from '@wordpress/element'; -import { useSelect, useDispatch } from '@wordpress/data'; -import { store as blockEditorStore } from '@wordpress/block-editor'; - -/** - * Internal dependencies - */ -import { PAGE_CONTENT_BLOCK_TYPES } from './constants'; - -export default function PageContentFlash( { contentRef } ) { - usePageContentFlash( contentRef ); - return null; -} - -export function usePageContentFlash( contentRef ) { - const { __experimentalGetGlobalBlocksByName } = - useSelect( blockEditorStore ); - - const { flashBlock } = useDispatch( blockEditorStore ); - - useEffect( () => { - const canvas = contentRef.current; - if ( ! canvas ) { - return; - } - const flashContentBlocks = () => { - const clientIds = __experimentalGetGlobalBlocksByName( - PAGE_CONTENT_BLOCK_TYPES - ); - for ( const clientId of clientIds ) { - flashBlock( clientId ); - } - }; - let timeout; - const handleClick = ( event ) => { - if ( - event.target.classList.contains( 'is-root-container' ) && - event.detail === 1 - ) { - timeout = setTimeout( flashContentBlocks, 300 ); - } - }; - const handleDblClick = ( event ) => { - if ( event.target.classList.contains( 'is-root-container' ) ) { - clearTimeout( timeout ); - } - }; - canvas.addEventListener( 'click', handleClick ); - canvas.addEventListener( 'dblclick', handleDblClick ); - return () => { - canvas.removeEventListener( 'click', handleClick ); - canvas.removeEventListener( 'dblclick', handleDblClick ); - }; - }, [ contentRef.current ] ); -} From 0ad5f1146b73df2441210a25f6a2739f0943a0d2 Mon Sep 17 00:00:00 2001 From: Robert Anderson Date: Wed, 14 Jun 2023 11:20:24 +1000 Subject: [PATCH 05/10] Show edit template notification if not already showing one --- .../edit-template-notification.js | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/packages/edit-site/src/components/page-content-focus-manager/edit-template-notification.js b/packages/edit-site/src/components/page-content-focus-manager/edit-template-notification.js index 124f3eb1d4ef7c..a15bfdc8be9a5d 100644 --- a/packages/edit-site/src/components/page-content-focus-manager/edit-template-notification.js +++ b/packages/edit-site/src/components/page-content-focus-manager/edit-template-notification.js @@ -38,20 +38,24 @@ function useEditTemplateNotification( contentRef ) { ( select ) => select( editSiteStore ).hasPageContentFocus(), [] ); - - const alreadySeen = useRef( false ); + const { getNotices } = useSelect( noticesStore ); const { createInfoNotice } = useDispatch( noticesStore ); const { setHasPageContentFocus } = useDispatch( editSiteStore ); + const lastNoticeId = useRef( 0 ); + useEffect( () => { - const handleClick = ( event ) => { + const handleClick = async ( event ) => { + const isNoticeAlreadyShowing = getNotices().some( + ( notice ) => notice.id === lastNoticeId.current + ); if ( - ! alreadySeen.current && + ! isNoticeAlreadyShowing && hasPageContentFocus && event.target.classList.contains( 'is-root-container' ) ) { - createInfoNotice( + const { notice } = await createInfoNotice( __( 'Edit your template to edit this block' ), { isDismissible: true, @@ -64,11 +68,11 @@ function useEditTemplateNotification( contentRef ) { ], } ); - alreadySeen.current = true; + lastNoticeId.current = notice.id; } }; const canvas = contentRef.current; canvas?.addEventListener( 'click', handleClick ); return () => canvas?.removeEventListener( 'click', handleClick ); - }, [ alreadySeen, hasPageContentFocus, contentRef.current ] ); + }, [ lastNoticeId, hasPageContentFocus, contentRef.current ] ); } From 4d1cda0fdeae618feb4e59d36cd8f6f19d6f71ad Mon Sep 17 00:00:00 2001 From: Robert Anderson Date: Wed, 14 Jun 2023 11:23:27 +1000 Subject: [PATCH 06/10] Oops, this doesn't belong here --- packages/block-editor/src/components/block-list/content.scss | 5 ----- 1 file changed, 5 deletions(-) diff --git a/packages/block-editor/src/components/block-list/content.scss b/packages/block-editor/src/components/block-list/content.scss index 783d48bfcc844d..a163ddaa789551 100644 --- a/packages/block-editor/src/components/block-list/content.scss +++ b/packages/block-editor/src/components/block-list/content.scss @@ -108,11 +108,6 @@ .is-dark-theme & { box-shadow: 0 0 0 var(--wp-admin-border-width-focus) $dark-theme-focus; } - - transition: - border-color 0.1s linear, - border-style 0.1s linear, - box-shadow 0.1s linear; } } From 9de65d5f93ae744b14480e696cbd67fbf6c67570 Mon Sep 17 00:00:00 2001 From: Robert Anderson Date: Wed, 14 Jun 2023 11:23:57 +1000 Subject: [PATCH 07/10] Restore packages/block-editor from trunk --- packages/block-editor/src/store/reducer.js | 45 ++++++++------------ packages/block-editor/src/store/selectors.js | 4 +- 2 files changed, 20 insertions(+), 29 deletions(-) diff --git a/packages/block-editor/src/store/reducer.js b/packages/block-editor/src/store/reducer.js index 7fa976f78e7bf7..b851c0293c8f16 100644 --- a/packages/block-editor/src/store/reducer.js +++ b/packages/block-editor/src/store/reducer.js @@ -1759,38 +1759,29 @@ export function lastBlockAttributesChange( state = null, action ) { } /** - * Reducer returning map of block client IDs to whether or not they are - * highlighted. + * Reducer returning current highlighted block. * - * @param {Object} state Current state. - * @param {Object} action Dispatched action. + * @param {boolean} state Current highlighted block. + * @param {Object} action Dispatched action. * - * @return {Object} Updated state. + * @return {string} Updated state. */ -export function highlightedBlocks( state = {}, action ) { +export function highlightedBlock( state, action ) { switch ( action.type ) { - case 'TOGGLE_BLOCK_HIGHLIGHT': { - if ( action.isHighlighted ) { - if ( ! state[ action.clientId ] ) { - return { - ...state, - [ action.clientId ]: true, - }; - } - } else if ( state[ action.clientId ] ) { - const nextState = { ...state }; - delete nextState[ action.clientId ]; - return nextState; + case 'TOGGLE_BLOCK_HIGHLIGHT': + const { clientId, isHighlighted } = action; + + if ( isHighlighted ) { + return clientId; + } else if ( state === clientId ) { + return null; } - break; - } - case 'SELECT_BLOCK': { - if ( state[ action.clientId ] ) { - const nextState = { ...state }; - delete nextState[ action.clientId ]; - return nextState; + + return state; + case 'SELECT_BLOCK': + if ( action.clientId !== state ) { + return null; } - } } return state; @@ -1885,7 +1876,7 @@ const combinedReducers = combineReducers( { lastBlockAttributesChange, editorMode, hasBlockMovingClientId, - highlightedBlocks, + highlightedBlock, lastBlockInserted, temporarilyEditingAsBlocks, blockVisibility, diff --git a/packages/block-editor/src/store/selectors.js b/packages/block-editor/src/store/selectors.js index 53037fd2d6d51a..10bf42ec230945 100644 --- a/packages/block-editor/src/store/selectors.js +++ b/packages/block-editor/src/store/selectors.js @@ -2676,7 +2676,7 @@ export function didAutomaticChange( state ) { * @return {boolean} Whether the block is currently highlighted. */ export function isBlockHighlighted( state, clientId ) { - return !! state.highlightedBlocks[ clientId ]; + return state.highlightedBlock === clientId; } /** @@ -2822,7 +2822,7 @@ export function __unstableHasActiveBlockOverlayActive( state, clientId ) { // Prevent overlay on disabled blocks. It's redundant since disabled blocks // can't be selected, and prevents non-disabled nested blocks from being // selected. - if ( getBlockEditingMode( state, clientId ) !== 'default' ) { + if ( getBlockEditingMode( state, clientId ) === 'disabled' ) { return false; } From 1f946eb0cac12873a6d2bff24bbaf9d7dd68b30a Mon Sep 17 00:00:00 2001 From: Robert Anderson Date: Mon, 19 Jun 2023 10:15:37 +1000 Subject: [PATCH 08/10] Optimise if() --- .../edit-template-notification.js | 41 ++++++++++--------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/packages/edit-site/src/components/page-content-focus-manager/edit-template-notification.js b/packages/edit-site/src/components/page-content-focus-manager/edit-template-notification.js index a15bfdc8be9a5d..2846acfff41ce1 100644 --- a/packages/edit-site/src/components/page-content-focus-manager/edit-template-notification.js +++ b/packages/edit-site/src/components/page-content-focus-manager/edit-template-notification.js @@ -47,29 +47,32 @@ function useEditTemplateNotification( contentRef ) { useEffect( () => { const handleClick = async ( event ) => { + if ( ! hasPageContentFocus ) { + return; + } + if ( ! event.target.classList.contains( 'is-root-container' ) ) { + return; + } const isNoticeAlreadyShowing = getNotices().some( ( notice ) => notice.id === lastNoticeId.current ); - if ( - ! isNoticeAlreadyShowing && - hasPageContentFocus && - event.target.classList.contains( 'is-root-container' ) - ) { - const { notice } = await createInfoNotice( - __( 'Edit your template to edit this block' ), - { - isDismissible: true, - type: 'snackbar', - actions: [ - { - label: __( 'Edit template' ), - onClick: () => setHasPageContentFocus( false ), - }, - ], - } - ); - lastNoticeId.current = notice.id; + if ( isNoticeAlreadyShowing ) { + return; } + const { notice } = await createInfoNotice( + __( 'Edit your template to edit this block' ), + { + isDismissible: true, + type: 'snackbar', + actions: [ + { + label: __( 'Edit template' ), + onClick: () => setHasPageContentFocus( false ), + }, + ], + } + ); + lastNoticeId.current = notice.id; }; const canvas = contentRef.current; canvas?.addEventListener( 'click', handleClick ); From 734d914ef420959f850eb15d5963209f1b9e3bd9 Mon Sep 17 00:00:00 2001 From: Robert Anderson Date: Mon, 19 Jun 2023 10:17:40 +1000 Subject: [PATCH 09/10] Add periods to notifications --- .../page-content-focus-manager/back-to-page-notification.js | 2 +- .../page-content-focus-manager/edit-template-notification.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/edit-site/src/components/page-content-focus-manager/back-to-page-notification.js b/packages/edit-site/src/components/page-content-focus-manager/back-to-page-notification.js index 2eb882cdbf847b..171d4b6a5f7579 100644 --- a/packages/edit-site/src/components/page-content-focus-manager/back-to-page-notification.js +++ b/packages/edit-site/src/components/page-content-focus-manager/back-to-page-notification.js @@ -42,7 +42,7 @@ export function useBackToPageNotification() { prevHasPageContentFocus.current && ! hasPageContentFocus ) { - createInfoNotice( __( 'You are editing a template' ), { + createInfoNotice( __( 'You are editing a template.' ), { isDismissible: true, type: 'snackbar', actions: [ diff --git a/packages/edit-site/src/components/page-content-focus-manager/edit-template-notification.js b/packages/edit-site/src/components/page-content-focus-manager/edit-template-notification.js index 2846acfff41ce1..4038428e9bf039 100644 --- a/packages/edit-site/src/components/page-content-focus-manager/edit-template-notification.js +++ b/packages/edit-site/src/components/page-content-focus-manager/edit-template-notification.js @@ -60,7 +60,7 @@ function useEditTemplateNotification( contentRef ) { return; } const { notice } = await createInfoNotice( - __( 'Edit your template to edit this block' ), + __( 'Edit your template to edit this block.' ), { isDismissible: true, type: 'snackbar', From f7ff0dc91511692045b4d907e82de9374ca9f50c Mon Sep 17 00:00:00 2001 From: Robert Anderson Date: Mon, 19 Jun 2023 11:43:06 +1000 Subject: [PATCH 10/10] Dismiss notification when opening dialog --- .../edit-template-dialog.js | 52 --------------- .../edit-template-notification.js | 65 +++++++++++++------ .../page-content-focus-manager/index.js | 8 +-- 3 files changed, 47 insertions(+), 78 deletions(-) delete mode 100644 packages/edit-site/src/components/page-content-focus-manager/edit-template-dialog.js diff --git a/packages/edit-site/src/components/page-content-focus-manager/edit-template-dialog.js b/packages/edit-site/src/components/page-content-focus-manager/edit-template-dialog.js deleted file mode 100644 index 0e31aa549f1c99..00000000000000 --- a/packages/edit-site/src/components/page-content-focus-manager/edit-template-dialog.js +++ /dev/null @@ -1,52 +0,0 @@ -/** - * WordPress dependencies - */ -import { useDispatch } from '@wordpress/data'; -import { useEffect, useState } from '@wordpress/element'; -import { __ } from '@wordpress/i18n'; -import { __experimentalConfirmDialog as ConfirmDialog } from '@wordpress/components'; - -/** - * Internal dependencies - */ -import { store as editSiteStore } from '../../store'; - -/** - * Component that displays a 'Edit your template to edit this block' - * notification when the user is focusing on editing page content and clicks on - * a disabled template block. - * - * @param {Object} props - * @param {import('react').RefObject} props.contentRef Ref to the block - * editor iframe canvas. - */ -export default function EditTemplateDialog( { contentRef } ) { - const [ isOpen, setIsOpen ] = useState( false ); - - useEffect( () => { - const handleDblClick = ( event ) => { - if ( event.target.classList.contains( 'is-root-container' ) ) { - setIsOpen( true ); - } - }; - const canvas = contentRef.current; - canvas?.addEventListener( 'dblclick', handleDblClick ); - return () => canvas?.removeEventListener( 'dblclick', handleDblClick ); - }, [ contentRef.current ] ); - - const { setHasPageContentFocus } = useDispatch( editSiteStore ); - - return ( - { - setIsOpen( false ); - setHasPageContentFocus( false ); - } } - onCancel={ () => setIsOpen( false ) } - > - { __( 'Edit your template to edit this block' ) } - - ); -} diff --git a/packages/edit-site/src/components/page-content-focus-manager/edit-template-notification.js b/packages/edit-site/src/components/page-content-focus-manager/edit-template-notification.js index 4038428e9bf039..3518bc8c3c51dc 100644 --- a/packages/edit-site/src/components/page-content-focus-manager/edit-template-notification.js +++ b/packages/edit-site/src/components/page-content-focus-manager/edit-template-notification.js @@ -2,9 +2,10 @@ * WordPress dependencies */ import { useSelect, useDispatch } from '@wordpress/data'; -import { useEffect, useRef } from '@wordpress/element'; +import { useEffect, useState, useRef } from '@wordpress/element'; import { store as noticesStore } from '@wordpress/notices'; import { __ } from '@wordpress/i18n'; +import { __experimentalConfirmDialog as ConfirmDialog } from '@wordpress/components'; /** * Internal dependencies @@ -12,37 +13,31 @@ import { __ } from '@wordpress/i18n'; import { store as editSiteStore } from '../../store'; /** - * Component that displays a 'Edit your template to edit this block' - * notification when the user is focusing on editing page content and clicks on - * a disabled template block. + * Component that: + * + * - Displays a 'Edit your template to edit this block' notification when the + * user is focusing on editing page content and clicks on a disabled template + * block. + * - Displays a 'Edit your template to edit this block' dialog when the user + * is focusing on editing page conetnt and double clicks on a disabled + * template block. * * @param {Object} props * @param {import('react').RefObject} props.contentRef Ref to the block * editor iframe canvas. */ export default function EditTemplateNotification( { contentRef } ) { - useEditTemplateNotification( contentRef ); - return null; -} - -/** - * Hook that displays a 'Edit your template to edit this block' notification - * when the user is focusing on editing page content and clicks on a disabled - * template block. - * - * @param {import('react').RefObject} contentRef Ref to the block - * editor iframe canvas. - */ -function useEditTemplateNotification( contentRef ) { const hasPageContentFocus = useSelect( ( select ) => select( editSiteStore ).hasPageContentFocus(), [] ); const { getNotices } = useSelect( noticesStore ); - const { createInfoNotice } = useDispatch( noticesStore ); + const { createInfoNotice, removeNotice } = useDispatch( noticesStore ); const { setHasPageContentFocus } = useDispatch( editSiteStore ); + const [ isDialogOpen, setIsDialogOpen ] = useState( false ); + const lastNoticeId = useRef( 0 ); useEffect( () => { @@ -74,8 +69,40 @@ function useEditTemplateNotification( contentRef ) { ); lastNoticeId.current = notice.id; }; + + const handleDblClick = ( event ) => { + if ( ! hasPageContentFocus ) { + return; + } + if ( ! event.target.classList.contains( 'is-root-container' ) ) { + return; + } + if ( lastNoticeId.current ) { + removeNotice( lastNoticeId.current ); + } + setIsDialogOpen( true ); + }; + const canvas = contentRef.current; canvas?.addEventListener( 'click', handleClick ); - return () => canvas?.removeEventListener( 'click', handleClick ); + canvas?.addEventListener( 'dblclick', handleDblClick ); + return () => { + canvas?.removeEventListener( 'click', handleClick ); + canvas?.removeEventListener( 'dblclick', handleDblClick ); + }; }, [ lastNoticeId, hasPageContentFocus, contentRef.current ] ); + + return ( + { + setIsDialogOpen( false ); + setHasPageContentFocus( false ); + } } + onCancel={ () => setIsDialogOpen( false ) } + > + { __( 'Edit your template to edit this block.' ) } + + ); } 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 0767be05cc8435..935ba1c96248cf 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 @@ -8,7 +8,6 @@ import { useSelect } from '@wordpress/data'; */ import { store as editSiteStore } from '../../store'; import DisableNonPageContentBlocks from './disable-non-page-content-blocks'; -import EditTemplateDialog from './edit-template-dialog'; import EditTemplateNotification from './edit-template-notification'; import BackToPageNotification from './back-to-page-notification'; @@ -19,12 +18,7 @@ export default function PageContentFocusManager( { contentRef } ) { ); return ( <> - { hasPageContentFocus && ( - <> - - - - ) } + { hasPageContentFocus && }