From 9eca467b47da387a1ade05e4db39ac7dea7f4139 Mon Sep 17 00:00:00 2001 From: Robert Anderson Date: Wed, 31 Jan 2024 10:50:44 +1100 Subject: [PATCH] Flash editable outlines on template patterns with templateLock = 'contentOnly' --- .../src/components/block-list/block.js | 6 +- .../block-list/use-block-props/index.js | 6 ++ .../use-flash-editable-blocks/index.js | 80 ++++++++++--------- packages/block-editor/src/private-apis.js | 2 +- packages/block-library/src/block/edit.js | 5 +- .../src/components/editor-canvas/index.js | 5 +- 6 files changed, 59 insertions(+), 45 deletions(-) diff --git a/packages/block-editor/src/components/block-list/block.js b/packages/block-editor/src/components/block-list/block.js index bbc03e05177b34..3f5c782b0717c5 100644 --- a/packages/block-editor/src/components/block-list/block.js +++ b/packages/block-editor/src/components/block-list/block.js @@ -538,7 +538,6 @@ function BlockListBlockProvider( props ) { getActiveBlockVariation, } = select( blocksStore ); const _isSelected = isBlockSelected( clientId ); - const templateLock = getTemplateLock( rootClientId ); const canRemove = canRemoveBlock( clientId, rootClientId ); const canMove = canMoveBlock( clientId, rootClientId ); const { name: blockName, attributes, isValid } = block; @@ -559,7 +558,8 @@ function BlockListBlockProvider( props ) { return { mode: getBlockMode( clientId ), isSelectionEnabled: isSelectionEnabled(), - isLocked: !! templateLock, + isLocked: !! getTemplateLock( rootClientId ), + templateLock: getTemplateLock( clientId ), canRemove, canMove, // Users of the editor.BlockListBlock filter used to be able to @@ -663,6 +663,7 @@ function BlockListBlockProvider( props ) { removeOutline, isBlockMovingMode, canInsertMovingBlock, + templateLock, isEditingDisabled, hasEditableOutline, className, @@ -699,6 +700,7 @@ function BlockListBlockProvider( props ) { removeOutline, isBlockMovingMode, canInsertMovingBlock, + templateLock, isEditingDisabled, hasEditableOutline, isTemporarilyEditingAsBlocks, diff --git a/packages/block-editor/src/components/block-list/use-block-props/index.js b/packages/block-editor/src/components/block-list/use-block-props/index.js index 7f3b9f1bb05e24..08b43fa46257e4 100644 --- a/packages/block-editor/src/components/block-list/use-block-props/index.js +++ b/packages/block-editor/src/components/block-list/use-block-props/index.js @@ -25,6 +25,7 @@ import { useEventHandlers } from './use-selected-block-event-handlers'; import { useNavModeExit } from './use-nav-mode-exit'; import { useBlockRefProvider } from './use-block-refs'; import { useIntersectionObserver } from './use-intersection-observer'; +import { useFlashEditableBlocks } from '../../use-flash-editable-blocks'; /** * This hook is used to lightly mark an element as a block element. The element @@ -98,6 +99,7 @@ export function useBlockProps( props = {}, { __unstableIsHtml } = {} ) { hasEditableOutline, isTemporarilyEditingAsBlocks, defaultClassName, + templateLock, } = useContext( PrivateBlockContext ); // translators: %s: Type of block (i.e. Text, Image etc) @@ -114,6 +116,10 @@ export function useBlockProps( props = {}, { __unstableIsHtml } = {} ) { useIntersectionObserver(), useMovingAnimation( { triggerAnimationOnChange: index, clientId } ), useDisabled( { isDisabled: ! hasOverlay } ), + useFlashEditableBlocks( { + clientId, + isEnabled: name === 'core/block' || templateLock === 'contentOnly', + } ), ] ); const blockEditContext = useBlockEditContext(); diff --git a/packages/block-editor/src/components/use-flash-editable-blocks/index.js b/packages/block-editor/src/components/use-flash-editable-blocks/index.js index 56e4e64a17ec86..34386ea8eadf3b 100644 --- a/packages/block-editor/src/components/use-flash-editable-blocks/index.js +++ b/packages/block-editor/src/components/use-flash-editable-blocks/index.js @@ -10,45 +10,53 @@ import { useSelect } from '@wordpress/data'; import { store as blockEditorStore } from '../../store'; import { unlock } from '../../lock-unlock'; -export default function useFlashEditableBlocks( rootClientId = '' ) { +export function useFlashEditableBlocks( { + clientId = '', + isEnabled = true, +} = {} ) { const { getEnabledClientIdsTree } = unlock( useSelect( blockEditorStore ) ); - return useRefEffect( ( element ) => { - const flashEditableBlocks = () => { - getEnabledClientIdsTree( rootClientId ).forEach( - ( { clientId } ) => { - const blockElement = element.querySelector( - `[data-block="${ clientId }"]` - ); - if ( ! blockElement ) { - return; - } - blockElement.classList.remove( 'has-editable-outline' ); - // Force reflow to trigger the animation. - // eslint-disable-next-line no-unused-expressions - blockElement.offsetWidth; - blockElement.classList.add( 'has-editable-outline' ); - } - ); - }; - - const handleClick = ( event ) => { - const shouldFlash = - event.target === element || - event.target.classList.contains( 'is-root-container' ); - if ( ! shouldFlash ) { - return; - } - if ( event.defaultPrevented ) { + return useRefEffect( + ( element ) => { + if ( ! isEnabled ) { return; } - event.preventDefault(); - flashEditableBlocks(); - }; - element.addEventListener( 'click', handleClick ); - return () => { - element.removeEventListener( 'click', handleClick ); - }; - } ); + const flashEditableBlocks = () => { + getEnabledClientIdsTree( clientId ).forEach( + ( { clientId: id } ) => { + const block = element.querySelector( + `[data-block="${ id }"]` + ); + if ( ! block ) { + return; + } + block.classList.remove( 'has-editable-outline' ); + // Force reflow to trigger the animation. + // eslint-disable-next-line no-unused-expressions + block.offsetWidth; + block.classList.add( 'has-editable-outline' ); + } + ); + }; + + const handleClick = ( event ) => { + const shouldFlash = + event.target === element || + event.target.classList.contains( 'is-root-container' ); + if ( ! shouldFlash ) { + return; + } + if ( event.defaultPrevented ) { + return; + } + event.preventDefault(); + flashEditableBlocks(); + }; + + element.addEventListener( 'click', handleClick ); + return () => element.removeEventListener( 'click', handleClick ); + }, + [ isEnabled ] + ); } diff --git a/packages/block-editor/src/private-apis.js b/packages/block-editor/src/private-apis.js index 555d0dd574fef7..2f9c5a70952d92 100644 --- a/packages/block-editor/src/private-apis.js +++ b/packages/block-editor/src/private-apis.js @@ -24,7 +24,7 @@ import { import { usesContextKey } from './components/rich-text/format-edit'; import { ExperimentalBlockCanvas } from './components/block-canvas'; import { getDuotoneFilter } from './components/duotone/utils'; -import useFlashEditableBlocks from './components/use-flash-editable-blocks'; +import { useFlashEditableBlocks } from './components/use-flash-editable-blocks'; /** * Private @wordpress/block-editor APIs. diff --git a/packages/block-library/src/block/edit.js b/packages/block-library/src/block/edit.js index 082de9453b0594..c940f36e1a8b86 100644 --- a/packages/block-library/src/block/edit.js +++ b/packages/block-library/src/block/edit.js @@ -35,9 +35,7 @@ import { parse, cloneBlock } from '@wordpress/blocks'; */ import { unlock } from '../lock-unlock'; -const { useLayoutClasses, useFlashEditableBlocks } = unlock( - blockEditorPrivateApis -); +const { useLayoutClasses } = unlock( blockEditorPrivateApis ); const { PARTIAL_SYNCING_SUPPORTED_BLOCKS } = unlock( patternsPrivateApis ); function isPartiallySynced( block ) { @@ -314,7 +312,6 @@ export default function ReusableBlockEdit( { const layoutClasses = useLayoutClasses( { layout }, name ); const blockProps = useBlockProps( { - ref: useFlashEditableBlocks( patternClientId ), className: classnames( 'block-library-block__reusable-block-container', layout && layoutClasses, diff --git a/packages/editor/src/components/editor-canvas/index.js b/packages/editor/src/components/editor-canvas/index.js index 083089892c6926..d012817e62ef4c 100644 --- a/packages/editor/src/components/editor-canvas/index.js +++ b/packages/editor/src/components/editor-canvas/index.js @@ -288,11 +288,12 @@ function EditorCanvas( { const localRef = useRef(); const typewriterRef = useTypewriter(); - const flashEditableBlocksRef = useFlashEditableBlocks(); const contentRef = useMergeRefs( [ localRef, renderingMode === 'post-only' ? typewriterRef : noop, - renderingMode === 'template-locked' ? flashEditableBlocksRef : noop, + useFlashEditableBlocks( { + isEnabled: renderingMode === 'template-locked', + } ), ] ); return (