Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Flash editable block outlines instead of always showing them #58159

Merged
merged 7 commits into from
Jan 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions packages/block-editor/src/components/block-list/block.js
Original file line number Diff line number Diff line change
Expand Up @@ -519,7 +519,6 @@ function BlockListBlockProvider( props ) {
isBlockBeingDragged,
hasBlockMovingClientId,
canInsertBlockType,
getBlockRootClientId,
__unstableHasActiveBlockOverlayActive,
__unstableGetEditorMode,
getSelectedBlocksInitialCaretPosition,
Expand All @@ -539,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;
Expand All @@ -556,10 +554,12 @@ function BlockListBlockProvider( props ) {
const hasLightBlockWrapper = blockType?.apiVersion > 1;
const movingClientId = hasBlockMovingClientId();
const blockEditingMode = getBlockEditingMode( clientId );

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
Expand Down Expand Up @@ -614,9 +614,12 @@ function BlockListBlockProvider( props ) {
movingClientId &&
canInsertBlockType(
getBlockName( movingClientId ),
getBlockRootClientId( clientId )
rootClientId
),
isEditingDisabled: blockEditingMode === 'disabled',
hasEditableOutline:
blockEditingMode !== 'disabled' &&
getBlockEditingMode( rootClientId ) === 'disabled',
className: hasLightBlockWrapper
? attributes.className
: undefined,
Expand Down Expand Up @@ -660,7 +663,9 @@ function BlockListBlockProvider( props ) {
removeOutline,
isBlockMovingMode,
canInsertMovingBlock,
templateLock,
isEditingDisabled,
hasEditableOutline,
className,
defaultClassName,
} = selectedProps;
Expand Down Expand Up @@ -695,7 +700,9 @@ function BlockListBlockProvider( props ) {
removeOutline,
isBlockMovingMode,
canInsertMovingBlock,
templateLock,
isEditingDisabled,
hasEditableOutline,
isTemporarilyEditingAsBlocks,
defaultClassName,
mayDisplayControls,
Expand Down
51 changes: 23 additions & 28 deletions packages/block-editor/src/components/block-list/content.scss
Original file line number Diff line number Diff line change
Expand Up @@ -300,35 +300,30 @@ _::-webkit-full-page-media, _:future, :root .has-multi-selection .block-editor-b
}
}

// Indicate which blocks are editable within a locked context.
// 1. User must be hovering an editor with renderingMode = 'template-lock'; or...
.is-template-locked:hover,
// ...a container block.
.block-editor-block-list__block:hover {
// 2. Look for locked blocks; or...
.block-editor-block-list__block.is-editing-disabled,
// ...container blocks that have locked children.
&:has(> .block-editor-block-list__block.is-editing-disabled) {
// 3. Highlight any unlocked children of that locked block.
& > .block-editor-block-list__block:not(.is-editing-disabled):not(.is-selected):not(.has-child-selected) {
&::after {
content: "";
border-style: dotted;
position: absolute;
pointer-events: none;
top: $border-width;
left: $border-width;
right: $border-width;
bottom: $border-width;
border: 1px dotted var(--wp-admin-theme-color);
border-radius: $radius-block-ui - $border-width;
}
@keyframes block-editor-has-editable-outline__fade-out-animation {
from {
border-color: rgba(var(--wp-admin-theme-color--rgb), 1);
}
to {
border-color: rgba(var(--wp-admin-theme-color--rgb), 0);
}
}

&.is-hovered::after {
background: rgba(var(--wp-admin-theme-color--rgb), 0.1);
border: none;
}
}
.is-root-container:not([inert]) .block-editor-block-list__block.has-editable-outline {
&::after {
content: "";
position: absolute;
pointer-events: none;
top: 0;
left: 0;
right: 0;
bottom: 0;
border: 1px dotted rgba(var(--wp-admin-theme-color--rgb), 1);
border-radius: $radius-block-ui;
animation: block-editor-has-editable-outline__fade-out-animation 0.3s ease-out;
animation-delay: 1s;
animation-fill-mode: forwards;
@include reduce-motion("animation");
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -95,8 +96,10 @@ export function useBlockProps( props = {}, { __unstableIsHtml } = {} ) {
isBlockMovingMode,
canInsertMovingBlock,
isEditingDisabled,
hasEditableOutline,
isTemporarilyEditingAsBlocks,
defaultClassName,
templateLock,
} = useContext( PrivateBlockContext );

// translators: %s: Type of block (i.e. Text, Image etc)
Expand All @@ -113,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();
Expand Down Expand Up @@ -152,6 +159,7 @@ export function useBlockProps( props = {}, { __unstableIsHtml } = {} ) {
'is-block-moving-mode': isBlockMovingMode,
'can-insert-moving-block': canInsertMovingBlock,
'is-editing-disabled': isEditingDisabled,
'has-editable-outline': hasEditableOutline,
'is-content-locked-temporarily-editing-as-blocks':
isTemporarilyEditingAsBlocks,
},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/**
* WordPress dependencies
*/
import { useRefEffect } from '@wordpress/compose';
import { useSelect } from '@wordpress/data';

/**
* Internal dependencies
*/
import { store as blockEditorStore } from '../../store';
import { unlock } from '../../lock-unlock';

export function useFlashEditableBlocks( {
clientId = '',
isEnabled = true,
} = {} ) {
const { getEnabledClientIdsTree } = unlock( useSelect( blockEditorStore ) );

return useRefEffect(
( element ) => {
if ( ! isEnabled ) {
return;
}

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' );
Comment on lines +34 to +38
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, clever!

}
);
};

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 ]
);
}
2 changes: 2 additions & 0 deletions packages/block-editor/src/private-apis.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +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';

/**
* Private @wordpress/block-editor APIs.
Expand Down Expand Up @@ -52,4 +53,5 @@ lock( privateApis, {
ReusableBlocksRenameHint,
useReusableBlocksRenameHint,
usesContextKey,
useFlashEditableBlocks,
} );
Original file line number Diff line number Diff line change
Expand Up @@ -27,27 +27,18 @@ import { store as editorStore } from '../../store';
* editor iframe canvas.
*/
export default function EditTemplateBlocksNotification( { contentRef } ) {
const { renderingMode, getPostLinkProps, templateId } = useSelect(
( select ) => {
const {
getRenderingMode,
getEditorSettings,
getCurrentTemplateId,
} = select( editorStore );
return {
renderingMode: getRenderingMode(),
getPostLinkProps: getEditorSettings().getPostLinkProps,
templateId: getCurrentTemplateId(),
};
},
[]
);
const editTemplate = getPostLinkProps
? getPostLinkProps( {
postId: templateId,
postType: 'wp_template',
} )
: {};
const editTemplate = useSelect( ( select ) => {
const { getEditorSettings, getCurrentTemplateId } =
select( editorStore );
const { getPostLinkProps } = getEditorSettings();
return getPostLinkProps
? getPostLinkProps( {
postId: getCurrentTemplateId(),
postType: 'wp_template',
} )
: {};
}, [] );

const { getNotices } = useSelect( noticesStore );

const { createInfoNotice, removeNotice } = useDispatch( noticesStore );
Expand All @@ -58,18 +49,17 @@ export default function EditTemplateBlocksNotification( { contentRef } ) {

useEffect( () => {
const handleClick = async ( event ) => {
if ( renderingMode !== 'template-locked' ) {
return;
}
Comment on lines -61 to -63
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just double-checking that I'm following correctly: the renderingMode is removed from the checks in the click and double click handler because we're moving the check up to where the component is being output instead of making it internal to the component?

Copy link
Member Author

@noisysocks noisysocks Jan 31, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah you have it right.

It's not necessary for this PR at all—leftover code from some explorations I was doing that went nowhere.

But I kept these changes as I think it's much nicer to simply not mount the component at all if it's not needed rather than unnecessarily mount the component and attach all these unnecessary event listeners that run unnecessary code on every click.

if ( ! event.target.classList.contains( 'is-root-container' ) ) {
return;
}

const isNoticeAlreadyShowing = getNotices().some(
( notice ) => notice.id === lastNoticeId.current
);
if ( isNoticeAlreadyShowing ) {
return;
}

const { notice } = await createInfoNotice(
__( 'Edit your template to edit this block.' ),
{
Expand All @@ -87,9 +77,6 @@ export default function EditTemplateBlocksNotification( { contentRef } ) {
};

const handleDblClick = ( event ) => {
if ( renderingMode !== 'template-locked' ) {
return;
}
if ( ! event.target.classList.contains( 'is-root-container' ) ) {
return;
}
Expand All @@ -106,7 +93,7 @@ export default function EditTemplateBlocksNotification( { contentRef } ) {
canvas?.removeEventListener( 'click', handleClick );
canvas?.removeEventListener( 'dblclick', handleDblClick );
};
}, [ lastNoticeId, renderingMode, contentRef.current ] );
}, [ lastNoticeId, contentRef.current ] );

return (
<ConfirmDialog
Expand Down
11 changes: 8 additions & 3 deletions packages/editor/src/components/editor-canvas/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ const {
useLayoutClasses,
useLayoutStyles,
ExperimentalBlockCanvas: BlockCanvas,
useFlashEditableBlocks,
} = unlock( blockEditorPrivateApis );

const noop = () => {};
Expand Down Expand Up @@ -290,6 +291,9 @@ function EditorCanvas( {
const contentRef = useMergeRefs( [
localRef,
renderingMode === 'post-only' ? typewriterRef : noop,
useFlashEditableBlocks( {
isEnabled: renderingMode === 'template-locked',
} ),
] );

return (
Expand Down Expand Up @@ -364,8 +368,7 @@ function EditorCanvas( {
'is-' + deviceType.toLowerCase() + '-preview',
renderingMode !== 'post-only'
? 'wp-site-blocks'
: `${ blockListLayoutClass } wp-block-post-content`, // Ensure root level blocks receive default/flow blockGap styling rules.
renderingMode !== 'all' && 'is-' + renderingMode
: `${ blockListLayoutClass } wp-block-post-content` // Ensure root level blocks receive default/flow blockGap styling rules.
) }
layout={ blockListLayout }
dropZoneElement={
Expand All @@ -377,7 +380,9 @@ function EditorCanvas( {
}
renderAppender={ renderAppender }
/>
<EditTemplateBlocksNotification contentRef={ localRef } />
{ renderingMode === 'template-locked' && (
<EditTemplateBlocksNotification contentRef={ localRef } />
) }
</RecursionProvider>
{ children }
</BlockCanvas>
Expand Down
Loading