Skip to content

Commit

Permalink
Update the block overlay to rely on useDisabled hook (#40649)
Browse files Browse the repository at this point in the history
  • Loading branch information
youknowriad committed May 6, 2022
1 parent c4c3173 commit a50c717
Show file tree
Hide file tree
Showing 12 changed files with 251 additions and 249 deletions.
1 change: 1 addition & 0 deletions packages/block-editor/README.md
Expand Up @@ -724,6 +724,7 @@ _Parameters_
- _props_ `Object`: Optional. Props to pass to the element. Must contain the ref if one is defined.
- _options_ `Object`: Options for internal use only.
- _options.\_\_unstableIsHtml_ `boolean`:
- _options.\_\_unstableIsDisabled_ `boolean`: Whether the block should be disabled.

_Returns_

Expand Down
103 changes: 8 additions & 95 deletions packages/block-editor/src/components/block-content-overlay/index.js
Expand Up @@ -2,114 +2,27 @@
* WordPress dependencies
*/
import { useSelect } from '@wordpress/data';
import { useState, useEffect } from '@wordpress/element';

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

/**
* External dependencies
*/
import classnames from 'classnames';

export default function BlockContentOverlay( {
clientId,
tagName: TagName = 'div',
wrapperProps,
className,
} ) {
const baseClassName = 'block-editor-block-content-overlay';
const [ isOverlayActive, setIsOverlayActive ] = useState( true );
const [ isHovered, setIsHovered ] = useState( false );

const {
canEdit,
isParentSelected,
hasChildSelected,
isDraggingBlocks,
isParentHighlighted,
} = useSelect(
export default function useBlockOverlayActive( clientId ) {
return useSelect(
( select ) => {
const {
isBlockSelected,
hasSelectedInnerBlock,
isDraggingBlocks: _isDraggingBlocks,
isBlockHighlighted,
canEditBlock,
} = select( blockEditorStore );
return {
canEdit: canEditBlock( clientId ),
isParentSelected: isBlockSelected( clientId ),
hasChildSelected: hasSelectedInnerBlock( clientId, true ),
isDraggingBlocks: _isDraggingBlocks(),
isParentHighlighted: isBlockHighlighted( clientId ),
};

return (
! canEditBlock( clientId ) ||
( ! isBlockSelected( clientId ) &&
! hasSelectedInnerBlock( clientId, true ) )
);
},
[ clientId ]
);

const classes = classnames(
baseClassName,
wrapperProps?.className,
className,
{
'overlay-active': isOverlayActive,
'parent-highlighted': isParentHighlighted,
'is-dragging-blocks': isDraggingBlocks,
}
);

useEffect( () => {
// The overlay is always active when editing is locked.
if ( ! canEdit ) {
setIsOverlayActive( true );
return;
}

// Reenable when blocks are not in use.
if ( ! isParentSelected && ! hasChildSelected && ! isOverlayActive ) {
setIsOverlayActive( true );
}
// Disable if parent selected by another means (such as list view).
// We check hover to ensure the overlay click interaction is not taking place.
// Trying to click the overlay will select the parent block via its 'focusin'
// listener on the wrapper, so if the block is selected while hovered we will
// let the mouseup disable the overlay instead.
if ( isParentSelected && ! isHovered && isOverlayActive ) {
setIsOverlayActive( false );
}
// Ensure overlay is disabled if a child block is selected.
if ( hasChildSelected && isOverlayActive ) {
setIsOverlayActive( false );
}
}, [
isParentSelected,
hasChildSelected,
isOverlayActive,
isHovered,
canEdit,
] );

// Disabled because the overlay div doesn't actually have a role or functionality
// as far as the a11y is concerned. We're just catching the first click so that
// the block can be selected without interacting with its contents.
/* eslint-disable jsx-a11y/no-static-element-interactions */
return (
<TagName
{ ...wrapperProps }
className={ classes }
onMouseEnter={ () => setIsHovered( true ) }
onMouseLeave={ () => setIsHovered( false ) }
onMouseUp={
isOverlayActive && canEdit
? () => setIsOverlayActive( false )
: undefined
}
>
{ wrapperProps?.children }
</TagName>
);
}
/* eslint-enable jsx-a11y/no-static-element-interactions */
@@ -1,5 +1,5 @@
.block-editor-block-content-overlay {
&.overlay-active::before {
&::before {
content: "";
position: absolute;
top: 0;
Expand All @@ -12,17 +12,8 @@
z-index: z-index(".block-editor-block-content-overlay__overlay");
}

&:hover:not(.is-dragging-blocks).overlay-active::before,
&.parent-highlighted.overlay-active::before {
&:hover:not(.is-dragging-blocks)::before {
background: rgba(var(--wp-admin-theme-color--rgb), 0.1);
box-shadow: 0 0 0 $border-width var(--wp-admin-theme-color) inset;
}

&.overlay-active:not(.is-dragging-blocks) * {
pointer-events: none;
}

&.is-dragging-blocks {
box-shadow: 0 0 0 $border-width var(--wp-admin-theme-color);
}
}
Expand Up @@ -12,7 +12,10 @@ import {
__unstableGetBlockProps as getBlockProps,
getBlockType,
} from '@wordpress/blocks';
import { useMergeRefs } from '@wordpress/compose';
import {
useMergeRefs,
__experimentalUseDisabled as useIsDisabled,
} from '@wordpress/compose';
import { useSelect } from '@wordpress/data';
import warning from '@wordpress/warning';

Expand Down Expand Up @@ -50,14 +53,18 @@ const BLOCK_ANIMATION_THRESHOLD = 200;
* also pass any other props through this hook, and they will be merged and
* returned.
*
* @param {Object} props Optional. Props to pass to the element. Must contain
* the ref if one is defined.
* @param {Object} options Options for internal use only.
* @param {Object} props Optional. Props to pass to the element. Must contain
* the ref if one is defined.
* @param {Object} options Options for internal use only.
* @param {boolean} options.__unstableIsHtml
* @param {boolean} options.__unstableIsDisabled Whether the block should be disabled.
*
* @return {Object} Props to pass to the element to mark as a block.
*/
export function useBlockProps( props = {}, { __unstableIsHtml } = {} ) {
export function useBlockProps(
props = {},
{ __unstableIsHtml, __unstableIsDisabled = false } = {}
) {
const { clientId, className, wrapperProps = {}, isAligned } = useContext(
BlockListBlockContext
);
Expand Down Expand Up @@ -125,6 +132,7 @@ export function useBlockProps( props = {}, { __unstableIsHtml } = {} ) {
enableAnimation,
triggerAnimationOnChange: index,
} ),
useIsDisabled( { isDisabled: ! __unstableIsDisabled } ),
] );

const blockEditContext = useBlockEditContext();
Expand Down
Expand Up @@ -110,7 +110,7 @@ export function useInBetweenInserter() {
// Don't show the insertion point if a parent block has an "overlay"
// See https://github.com/WordPress/gutenberg/pull/34012#pullrequestreview-727762337
const parentOverlay = element.parentElement?.closest(
'.block-editor-block-content-overlay.overlay-active'
'.block-editor-block-content-overlay'
);
if ( parentOverlay ) {
return;
Expand Down
2 changes: 1 addition & 1 deletion packages/block-editor/src/components/index.js
Expand Up @@ -14,7 +14,7 @@ export {
export { default as __experimentalBlockFullHeightAligmentControl } from './block-full-height-alignment-control';
export { default as __experimentalBlockAlignmentMatrixControl } from './block-alignment-matrix-control';
export { default as BlockBreadcrumb } from './block-breadcrumb';
export { default as __experimentalBlockContentOverlay } from './block-content-overlay';
export { default as __experimentalUseBlockOverlayActive } from './block-content-overlay';
export { BlockContextProvider } from './block-context';
export {
default as BlockControls,
Expand Down
79 changes: 38 additions & 41 deletions packages/block-library/src/block/edit.js
Expand Up @@ -19,7 +19,7 @@ import { __ } from '@wordpress/i18n';
import {
useInnerBlocksProps,
__experimentalUseNoRecursiveRenders as useNoRecursiveRenders,
__experimentalBlockContentOverlay as BlockContentOverlay,
__experimentalUseBlockOverlayActive as useBlockOverlayActive,
InnerBlocks,
BlockControls,
InspectorControls,
Expand Down Expand Up @@ -62,20 +62,25 @@ export default function ReusableBlockEdit( { attributes: { ref }, clientId } ) {
ref
);

const blockProps = useBlockProps();

const innerBlocksProps = useInnerBlocksProps(
{},
const hasBlockOverlay = useBlockOverlayActive( clientId );
const blockProps = useBlockProps(
{
value: blocks,
onInput,
onChange,
renderAppender: blocks?.length
? undefined
: InnerBlocks.ButtonBlockAppender,
}
className: hasBlockOverlay
? 'block-library-block__reusable-block-container block-editor-block-content-overlay'
: 'block-library-block__reusable-block-container',
},
{ __unstableIsDisabled: hasBlockOverlay }
);

const innerBlocksProps = useInnerBlocksProps( blockProps, {
value: blocks,
onInput,
onChange,
renderAppender: blocks?.length
? undefined
: InnerBlocks.ButtonBlockAppender,
} );

if ( hasAlreadyRendered ) {
return (
<div { ...blockProps }>
Expand Down Expand Up @@ -108,36 +113,28 @@ export default function ReusableBlockEdit( { attributes: { ref }, clientId } ) {

return (
<RecursionProvider>
<div { ...blockProps }>
{ canRemove && (
<BlockControls>
<ToolbarGroup>
<ToolbarButton
onClick={ () =>
convertBlockToStatic( clientId )
}
label={ __( 'Convert to regular blocks' ) }
icon={ ungroup }
showTooltip
/>
</ToolbarGroup>
</BlockControls>
) }
<InspectorControls>
<PanelBody>
<TextControl
label={ __( 'Name' ) }
value={ title }
onChange={ setTitle }
{ canRemove && (
<BlockControls>
<ToolbarGroup>
<ToolbarButton
onClick={ () => convertBlockToStatic( clientId ) }
label={ __( 'Convert to regular blocks' ) }
icon={ ungroup }
showTooltip
/>
</PanelBody>
</InspectorControls>
<BlockContentOverlay
clientId={ clientId }
wrapperProps={ innerBlocksProps }
className="block-library-block__reusable-block-container"
/>
</div>
</ToolbarGroup>
</BlockControls>
) }
<InspectorControls>
<PanelBody>
<TextControl
label={ __( 'Name' ) }
value={ title }
onChange={ setTitle }
/>
</PanelBody>
</InspectorControls>
<div { ...innerBlocksProps } />
</RecursionProvider>
);
}
61 changes: 35 additions & 26 deletions packages/block-library/src/navigation/edit/index.js
Expand Up @@ -24,6 +24,7 @@ import {
ContrastChecker,
getColorClassName,
Warning,
__experimentalUseBlockOverlayActive as useBlockOverlayActive,
} from '@wordpress/block-editor';
import { EntityProvider } from '@wordpress/core-data';

Expand Down Expand Up @@ -320,33 +321,41 @@ function Navigation( {

const textDecoration = attributes.style?.typography?.textDecoration;

const blockProps = useBlockProps( {
ref: navRef,
className: classnames( className, {
'items-justified-right': justifyContent === 'right',
'items-justified-space-between': justifyContent === 'space-between',
'items-justified-left': justifyContent === 'left',
'items-justified-center': justifyContent === 'center',
'is-vertical': orientation === 'vertical',
'no-wrap': flexWrap === 'nowrap',
'is-responsive': 'never' !== overlayMenu,
'has-text-color': !! textColor.color || !! textColor?.class,
[ getColorClassName(
'color',
textColor?.slug
) ]: !! textColor?.slug,
'has-background': !! backgroundColor.color || backgroundColor.class,
[ getColorClassName(
'background-color',
backgroundColor?.slug
) ]: !! backgroundColor?.slug,
[ `has-text-decoration-${ textDecoration }` ]: textDecoration,
} ),
style: {
color: ! textColor?.slug && textColor?.color,
backgroundColor: ! backgroundColor?.slug && backgroundColor?.color,
const hasBlockOverlay = useBlockOverlayActive( clientId );
const blockProps = useBlockProps(
{
ref: navRef,
className: classnames( className, {
'items-justified-right': justifyContent === 'right',
'items-justified-space-between':
justifyContent === 'space-between',
'items-justified-left': justifyContent === 'left',
'items-justified-center': justifyContent === 'center',
'is-vertical': orientation === 'vertical',
'no-wrap': flexWrap === 'nowrap',
'is-responsive': 'never' !== overlayMenu,
'has-text-color': !! textColor.color || !! textColor?.class,
[ getColorClassName(
'color',
textColor?.slug
) ]: !! textColor?.slug,
'has-background':
!! backgroundColor.color || backgroundColor.class,
[ getColorClassName(
'background-color',
backgroundColor?.slug
) ]: !! backgroundColor?.slug,
[ `has-text-decoration-${ textDecoration }` ]: textDecoration,
'block-editor-block-content-overlay': hasBlockOverlay,
} ),
style: {
color: ! textColor?.slug && textColor?.color,
backgroundColor:
! backgroundColor?.slug && backgroundColor?.color,
},
},
} );
{ __unstableIsDisabled: hasBlockOverlay }
);

const overlayClassnames = classnames( {
'has-text-color':
Expand Down

0 comments on commit a50c717

Please sign in to comment.