Skip to content
Draft
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
62 changes: 47 additions & 15 deletions packages/block-editor/src/components/block-card/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ import {
Icon,
__experimentalText as Text,
__experimentalVStack as VStack,
__experimentalHStack as HStack,
privateApis as componentsPrivateApis,
Notice,
} from '@wordpress/components';
import { useDispatch, useSelect } from '@wordpress/data';
import deprecated from '@wordpress/deprecated';
Expand All @@ -21,6 +23,7 @@ import {
chevronRight,
arrowRight,
arrowLeft,
unseen,
} from '@wordpress/icons';

/**
Expand Down Expand Up @@ -119,6 +122,19 @@ function BlockCard( {
[ clientId, allowParentNavigation, isChild, parentClientId ]
);

const isBlockHidden = useSelect(
( select ) => {
if ( ! clientId ) {
return false;
}
const { isBlockHidden: _isBlockHidden } = unlock(
select( blockEditorStore )
);
return _isBlockHidden( clientId );
},
[ clientId ]
);

const { selectBlock } = useDispatch( blockEditorStore );

const TitleElement = parentClientId ? 'div' : 'h2';
Expand Down Expand Up @@ -166,22 +182,38 @@ function BlockCard( {
: undefined
}
>
<BlockIcon icon={ icon } showColors />
<VStack spacing={ 1 }>
<TitleElement className="block-editor-block-card__title">
<span className="block-editor-block-card__name">
{ !! name?.length ? name : title }
</span>
{ ! parentClientId && ! isChild && !! name?.length && (
<Badge>{ title }</Badge>
) }
</TitleElement>
{ ! parentClientId && ! isChild && description && (
<Text className="block-editor-block-card__description">
{ description }
</Text>
<VStack spacing={ 4 }>
<HStack spacing={ 1 } align="start">
<BlockIcon icon={ icon } showColors />
<VStack spacing={ 1 }>
<TitleElement className="block-editor-block-card__title">
<span className="block-editor-block-card__name">
{ !! name?.length ? name : title }
</span>
{ ! parentClientId &&
! isChild &&
!! name?.length && (
<Badge>{ title }</Badge>
) }
{ isBlockHidden && <Icon icon={ unseen } /> }
</TitleElement>
{ ! parentClientId && ! isChild && description && (
<Text className="block-editor-block-card__description">
{ description }
</Text>
) }
{ children }
</VStack>
</HStack>
{ isBlockHidden && (
<Notice
className="block-editor-block-card__hidden-notice"
status="warning"
isDismissible={ false }
>
{ __( 'Block is hidden' ) }
</Notice>
) }
{ children }
</VStack>
</OptionalParentSelectButton>
</div>
Expand Down
18 changes: 17 additions & 1 deletion packages/block-editor/src/components/block-card/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@

.block-editor-block-card__parent-select-button {
padding: 0;
align-items: start;
text-align: start;
height: auto !important;
}
Expand Down Expand Up @@ -54,3 +53,20 @@
color: var(--wp-block-synced-color);
}

.block-editor-block-card__hidden-indicator {
display: inline-flex;
align-items: center;
opacity: 0.6;
margin-left: $grid-unit-05;

svg {
width: 24px;
height: 24px;
fill: currentColor;
}
}

.block-editor-block-card__hidden-notice {
padding-top: $grid-unit-05;
padding-bottom: $grid-unit-05;
}
4 changes: 3 additions & 1 deletion packages/block-editor/src/components/block-list/block.js
Original file line number Diff line number Diff line change
Expand Up @@ -554,7 +554,7 @@ BlockListBlock = compose(
// context to pass the rest of the information to the filtered BlockListBlock
// component, and useBlockProps.
function BlockListBlockProvider( props ) {
const { clientId, rootClientId } = props;
const { clientId, rootClientId, showHiddenBlocksAsGhost } = props;
const selectedProps = useSelect(
( select ) => {
const {
Expand Down Expand Up @@ -818,11 +818,13 @@ function BlockListBlockProvider( props ) {
themeSupportsLayout,
canMove,
isBlockHidden,
showHiddenBlocksAsGhost: showHiddenBlocksAsGhost ?? false,
bindableAttributes,
};

if (
isBlockHidden &&
! showHiddenBlocksAsGhost &&
! isSelected &&
! isMultiSelected &&
! hasChildSelected
Expand Down
28 changes: 23 additions & 5 deletions packages/block-editor/src/components/block-list/content.scss
Original file line number Diff line number Diff line change
Expand Up @@ -102,19 +102,37 @@ _::-webkit-full-page-media, _:future, :root [data-has-multi-selection="true"] .b
// Hidden blocks.
// In order for the block toolbar to render correctly, blocks cannot be hidden.
// Instead, use styles to visually hide blocks.
.block-editor-block-list__block.is-block-hidden {
// Default: ghost state (visible but dimmed with visual indicator).
.block-editor-block-list__block.is-block-hidden:not(.is-selected):not(.is-multi-selected):not(.has-child-selected) {
opacity: 0.3;
border: 1px dashed currentColor;
position: relative;
background: repeating-linear-gradient(45deg, transparent, transparent 5px, rgba(0, 0, 0, 0.1) 5px, rgba(0, 0, 0, 0.1) 6px);
background-size: 12px 12px;
}

// Fully hidden state (when preference is disabled).
// Applies to all hidden blocks when ghost mode is off (selected or not).
.block-editor-block-list__block.is-fully-hidden {
visibility: hidden;
overflow: hidden;
height: 0;
border: none !important;
padding: 0 !important;
opacity: 0;
background: none;
position: fixed;
left: -9999px;
top: -9999px;
}

&.is-layout-flex:not(.is-vertical) > .is-block-hidden {
width: 0;
height: auto;
align-self: stretch;
white-space: nowrap !important;
&.is-fully-hidden {
width: 0;
height: auto;
align-self: stretch;
white-space: nowrap !important;
}
}

// Re-enable it on components inside.
Expand Down
11 changes: 9 additions & 2 deletions packages/block-editor/src/components/block-list/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ function Root( { className, ...settings } ) {
updates[ id ] = isIntersecting;
} );
setBlockVisibility( updates );
}, [ registry ] ),
}, [ registry, setBlockVisibility ] ),
300,
delayedBlockVisibilityDebounceOptions
);
Expand All @@ -100,7 +100,7 @@ function Root( { className, ...settings } ) {
}
delayedBlockVisibilityUpdates();
} );
}, [] );
}, [ registry, delayedBlockVisibilityUpdates ] );
const innerBlocksProps = useInnerBlocksProps(
{
ref: useMergeRefs( [
Expand Down Expand Up @@ -184,6 +184,7 @@ function Items( {
selectedBlocks,
visibleBlocks,
shouldRenderAppender,
showHiddenBlocksAsGhost,
} = useSelect(
( select ) => {
const {
Expand All @@ -210,6 +211,10 @@ function Items( {
};
}

const { shouldShowHiddenBlocksAsGhost } = unlock(
select( blockEditorStore )
);

const selectedBlockClientIds = getSelectedBlockClientIds();
const selectedBlockClientId = selectedBlockClientIds[ 0 ];
const showRootAppender =
Expand All @@ -233,6 +238,7 @@ function Items( {
selectedBlocks: selectedBlockClientIds,
visibleBlocks: __unstableGetVisibleBlocks(),
isZoomOut: _isZoomOut(),
showHiddenBlocksAsGhost: shouldShowHiddenBlocksAsGhost(),
shouldRenderAppender:
( ! isSectionBlock( rootClientId ) ||
isContainerInsertableToInContentOnlyMode(
Expand Down Expand Up @@ -273,6 +279,7 @@ function Items( {
<BlockListBlock
rootClientId={ rootClientId }
clientId={ clientId }
showHiddenBlocksAsGhost={ showHiddenBlocksAsGhost }
/>
{ isZoomOut && (
<ZoomOutSeparator
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,10 +103,21 @@ export function useBlockProps( props = {}, { __unstableIsHtml } = {} ) {
isWithinSectionBlock,
canMove,
isBlockHidden,
showHiddenBlocksAsGhost,
} = useContext( PrivateBlockContext );

// translators: %s: Type of block (i.e. Text, Image etc)
const blockLabel = sprintf( __( 'Block: %s' ), blockTitle );
const blockLabel = isBlockHidden
Copy link
Member Author

Choose a reason for hiding this comment

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

Is this the right place for this message? Do we even need it?

? sprintf(
/* translators: %1$s: Type of block (i.e. Text, Image etc), %2$s: Additional information about hidden state */
__( 'Block: %1$s. %2$s' ),
blockTitle,
__(
'This block is hidden and will not appear on the frontend of your site, but remains editable in the editor.'
)
)
: // translators: %s: Type of block (i.e. Text, Image etc)
sprintf( __( 'Block: %s' ), blockTitle );
const htmlSuffix = mode === 'html' && ! __unstableIsHtml ? '-visual' : '';
const ffDragRef = useFirefoxDraggableCompatibility();
const isHoverEnabled = ! isWithinSectionBlock;
Expand Down Expand Up @@ -185,7 +196,12 @@ export function useBlockProps( props = {}, { __unstableIsHtml } = {} ) {
'has-editable-outline': hasEditableOutline,
'has-negative-margin': hasNegativeMargin,
'is-editing-content-only-section': isEditingContentOnlySection,
'is-block-hidden': isBlockHidden,
'is-block-hidden':
isBlockHidden &&
( showHiddenBlocksAsGhost ?? false ) &&
! isSelected,
'is-fully-hidden':
isBlockHidden && ! ( showHiddenBlocksAsGhost ?? false ),
},
className,
props.className,
Expand Down
56 changes: 38 additions & 18 deletions packages/block-editor/src/components/list-view/block.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,25 +123,42 @@ function ListViewBlock( {

const pasteStyles = usePasteStyles();

const { block, blockName, allowRightClickOverrides, isBlockHidden } =
useSelect(
( select ) => {
const { getBlock, getBlockName, getSettings } =
select( blockEditorStore );
const { isBlockHidden: _isBlockHidden } = unlock(
select( blockEditorStore )
);
const {
block,
blockName,
allowRightClickOverrides,
isBlockHidden,
hasHiddenParent,
isRootParentSelected,
} = useSelect(
( select ) => {
const { getBlock, getBlockName, getSettings } =
select( blockEditorStore );
const { isBlockHidden: _isBlockHidden } = unlock(
select( blockEditorStore )
);

return {
block: getBlock( clientId ),
blockName: getBlockName( clientId ),
allowRightClickOverrides:
getSettings().allowRightClickOverrides,
isBlockHidden: _isBlockHidden( clientId ),
};
},
[ clientId ]
);
const parentClientIds = getBlockParents( clientId );
const _hasHiddenParent = parentClientIds.some( ( parentId ) =>
_isBlockHidden( parentId )
);

const rootClientId = getBlockRootClientId( clientId );
const _isRootParentSelected =
rootClientId && selectedClientIds.includes( rootClientId );

return {
block: getBlock( clientId ),
blockName: getBlockName( clientId ),
allowRightClickOverrides:
getSettings().allowRightClickOverrides,
isBlockHidden: _isBlockHidden( clientId ),
hasHiddenParent: _hasHiddenParent,
isRootParentSelected: _isRootParentSelected,
};
},
[ clientId, getBlockParents, getBlockRootClientId, selectedClientIds ]
);

const showBlockActions =
// When a block hides its toolbar it also hides the block settings menu,
Expand Down Expand Up @@ -561,6 +578,9 @@ function ListViewBlock( {
'is-displacement-down': displacement === 'down',
'is-after-dragged-blocks': isAfterDraggedBlocks,
'is-nesting': isNesting,
'is-block-hidden': isBlockHidden,
'has-hidden-parent':
hasHiddenParent && ! isSelected && ! isRootParentSelected,
} );

// Only include all selected blocks if the currently clicked on block
Expand Down
5 changes: 5 additions & 0 deletions packages/block-editor/src/components/list-view/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,11 @@
flex: 0 0 $icon-size;
}

&.is-block-hidden:not(.is-selected):not(.is-branch-selected),
&.has-hidden-parent:not(.is-selected):not(.is-branch-selected) {
opacity: 0.5;
}

.block-editor-list-view-block__menu-cell,
.block-editor-list-view-block__mover-cell,
.block-editor-list-view-block__contents-cell {
Expand Down
13 changes: 13 additions & 0 deletions packages/block-editor/src/store/private-actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -466,3 +466,16 @@ export function toggleBlockSpotlight( clientId, hasBlockSpotlight ) {
hasBlockSpotlight,
};
}

/**
* Action that toggles whether hidden blocks should be shown as ghost.
*
* @param {boolean} showHiddenBlocksAsGhost Whether to show hidden blocks as ghost.
* @return {Object} Action object.
*/
export function toggleShowHiddenBlocksAsGhost( showHiddenBlocksAsGhost ) {
return {
type: 'TOGGLE_SHOW_HIDDEN_BLOCKS_AS_GHOST',
showHiddenBlocksAsGhost,
};
}
11 changes: 11 additions & 0 deletions packages/block-editor/src/store/private-selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -738,6 +738,17 @@ export function hasBlockSpotlight( state ) {
return !! state.hasBlockSpotlight || !! state.editedContentOnlySection;
}

/**
* Returns true if hidden blocks should be shown as ghost, or false otherwise.
*
* @param {Object} state Global application state.
*
* @return {boolean} Whether hidden blocks should be shown as ghost.
*/
export function shouldShowHiddenBlocksAsGhost( state ) {
return state.showHiddenBlocksAsGhost ?? false;
}

/**
* Returns whether a block is locked to prevent editing.
*
Expand Down
Loading
Loading