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

Improve visual clarity of reusable block #28318

Merged
merged 12 commits into from
Jan 27, 2021
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,6 @@ import classnames from 'classnames';
/**
* WordPress dependencies
*/
import {
__experimentalGetBlockLabel as getBlockLabel,
getBlockType,
} from '@wordpress/blocks';
import { Button, VisuallyHidden } from '@wordpress/components';
import { useInstanceId } from '@wordpress/compose';
import { forwardRef } from '@wordpress/element';
Expand All @@ -22,11 +18,12 @@ import BlockIcon from '../block-icon';
import Indentation from './indentation';
import useBlockDisplayInformation from '../use-block-display-information';
import { getBlockPositionDescription } from './utils';
import BlockTitle from '../block-title';

function BlockNavigationBlockSelectButton(
{
className,
block: { clientId, name, attributes },
block: { clientId },
isSelected,
onClick,
position,
Expand All @@ -43,12 +40,6 @@ function BlockNavigationBlockSelectButton(
const blockInformation = useBlockDisplayInformation( clientId );
const instanceId = useInstanceId( BlockNavigationBlockSelectButton );
const descriptionId = `block-navigation-block-select-button__${ instanceId }`;
const blockType = getBlockType( name );
const blockLabel = getBlockLabel( blockType, attributes );
// If label is defined we prioritize it over possible possible
// block variation match title.
const blockDisplayName =
Copy link
Member Author

Choose a reason for hiding this comment

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

I don't recall why we were not using BlockTitle here instead of calculating again cc @youknowriad

Copy link
Contributor

Choose a reason for hiding this comment

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

There was a lengthy PR with a long discussion about the label here. I think @talldan was involved in it maybe? Though I don't have a direct answer.

Copy link
Contributor

@talldan talldan Jan 21, 2021

Choose a reason for hiding this comment

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

Looks like BlockTitle didn't show the label when this was initially implemented, but was later updated to do so.

Using BlockTitle here is a nice improvement.

blockLabel !== blockType.title ? blockLabel : blockInformation?.title;
const blockPositionDescription = getBlockPositionDescription(
position,
siblingBlockCount,
Expand All @@ -73,7 +64,7 @@ function BlockNavigationBlockSelectButton(
>
<Indentation level={ level } />
<BlockIcon icon={ blockInformation?.icon } showColors />
{ blockDisplayName }
<BlockTitle clientId={ clientId } />
{ isSelected && (
<VisuallyHidden>
{ __( '(selected block)' ) }
Expand Down
48 changes: 37 additions & 11 deletions packages/block-editor/src/components/block-switcher/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* External dependencies
*/
import { castArray, uniq } from 'lodash';
import { castArray, uniq, truncate } from 'lodash';

/**
* WordPress dependencies
Expand All @@ -13,7 +13,11 @@ import {
ToolbarGroup,
ToolbarItem,
} from '@wordpress/components';
import { switchToBlockType, store as blocksStore } from '@wordpress/blocks';
import {
switchToBlockType,
store as blocksStore,
isReusableBlock,
} from '@wordpress/blocks';
import { useSelect, useDispatch } from '@wordpress/data';
import { stack } from '@wordpress/icons';

Expand All @@ -36,9 +40,12 @@ export const BlockSwitcherDropdownMenu = ( { clientIds, blocks } ) => {
blockTitle,
} = useSelect(
( select ) => {
const { getBlockRootClientId, getBlockTransformItems } = select(
blockEditorStore
);
const {
getBlockRootClientId,
getBlockTransformItems,
__experimentalGetReusableBlockTitle,
} = select( blockEditorStore );

const { getBlockStyles, getBlockType } = select( blocksStore );
const rootClientId = getBlockRootClientId(
castArray( clientIds )[ 0 ]
Expand All @@ -48,8 +55,14 @@ export const BlockSwitcherDropdownMenu = ( { clientIds, blocks } ) => {
const styles =
_isSingleBlockSelected && getBlockStyles( firstBlockName );
let _icon;
let reusableBlockTitle;
if ( _isSingleBlockSelected ) {
_icon = blockInformation?.icon; // Take into account active block variations.
reusableBlockTitle =
isReusableBlock( blocks[ 0 ] ) &&
__experimentalGetReusableBlockTitle(
blocks[ 0 ].attributes.ref
);
} else {
const isSelectionOfSameType =
uniq( blocks.map( ( { name } ) => name ) ).length === 1;
Expand All @@ -59,19 +72,23 @@ export const BlockSwitcherDropdownMenu = ( { clientIds, blocks } ) => {
? getBlockType( firstBlockName )?.icon
: stack;
}

return {
possibleBlockTransformations: getBlockTransformItems(
blocks,
rootClientId
),
hasBlockStyles: !! styles?.length,
icon: _icon,
blockTitle: getBlockType( firstBlockName ).title,
blockTitle:
reusableBlockTitle || getBlockType( firstBlockName ).title,
};
},
[ clientIds, blocks, blockInformation?.icon ]
);

const isReusable = blocks.length === 1 && isReusableBlock( blocks[ 0 ] );

const onTransform = ( name ) =>
replaceBlocks( clientIds, switchToBlockType( blocks, name ) );
const hasPossibleBlockTransformations = !! possibleBlockTransformations.length;
Expand Down Expand Up @@ -116,11 +133,20 @@ export const BlockSwitcherDropdownMenu = ( { clientIds, blocks } ) => {
className: 'block-editor-block-switcher__popover',
} }
icon={
<BlockIcon
icon={ icon }
className="block-editor-block-switcher__toggle"
showColors
/>
<>
<BlockIcon
icon={ icon }
className="block-editor-block-switcher__toggle"
showColors
/>
{ isReusable && (
<span className="block-editor-block-switcher__toggle-text">
{ truncate( blockTitle, {
length: 35,
} ) }
</span>
) }
</>
}
toggleProps={ {
describedBy: blockSwitcherDescription,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@
}
}

.block-editor-block-switcher__toggle-text {
margin-left: $grid-unit-10;
}

// Indent the popover to match the button position.
.block-editor-block-switcher__popover {
margin-left: 6px;
Expand Down
26 changes: 21 additions & 5 deletions packages/block-editor/src/components/block-title/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { useSelect } from '@wordpress/data';
import {
getBlockType,
__experimentalGetBlockLabel as getBlockLabel,
isReusableBlock,
} from '@wordpress/blocks';

/**
Expand All @@ -33,17 +34,29 @@ import useBlockDisplayInformation from '../use-block-display-information';
* @return {?string} Block title.
*/
export default function BlockTitle( { clientId } ) {
const { attributes, name } = useSelect(
const { attributes, name, reusableBlockTitle } = useSelect(
( select ) => {
if ( ! clientId ) {
return {};
}
const { getBlockName, getBlockAttributes } = select(
'core/block-editor'
);
const {
getBlockName,
getBlockAttributes,
__experimentalGetReusableBlockTitle,
} = select( 'core/block-editor' );
const blockName = getBlockName( clientId );
if ( ! blockName ) {
return {};
}
const isReusable = isReusableBlock( getBlockType( blockName ) );
return {
attributes: getBlockAttributes( clientId ),
name: getBlockName( clientId ),
name: blockName,
reusableBlockTitle:
isReusable &&
__experimentalGetReusableBlockTitle(
getBlockAttributes( clientId ).ref
),
};
},
[ clientId ]
Expand All @@ -60,5 +73,8 @@ export default function BlockTitle( { clientId } ) {
if ( label !== blockType.title ) {
return `${ blockType.title }: ${ truncate( label, { length: 15 } ) }`;
}
if ( reusableBlockTitle ) {
return truncate( reusableBlockTitle, { length: 35 } );
}
return blockInformation.title;
}
23 changes: 23 additions & 0 deletions packages/block-editor/src/store/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -1817,6 +1817,29 @@ export const __experimentalGetParsedReusableBlock = createSelector(
( state ) => [ getReusableBlocks( state ) ]
);

/**
* Returns the title of a given reusable block
*
* @param {Object} state Global application state.
* @param {number|string} ref The shared block's ID.
*
* @return {string} The reusable block saved title.
*/
export const __experimentalGetReusableBlockTitle = createSelector(
( state, ref ) => {
const reusableBlock = find(
getReusableBlocks( state ),
( block ) => block.id === ref
);
if ( ! reusableBlock ) {
return null;
}

return reusableBlock.title?.raw;
},
( state ) => [ getReusableBlocks( state ) ]
);

/**
* Returns true if the most recent block change is be considered ignored, or
* false otherwise. An ignored change is one not to be committed by
Expand Down
8 changes: 5 additions & 3 deletions packages/block-library/src/block/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import {
Warning,
} from '@wordpress/block-editor';
import { store as reusableBlocksStore } from '@wordpress/reusable-blocks';
import { ungroup } from '@wordpress/icons';

export default function ReusableBlockEdit( { attributes: { ref }, clientId } ) {
const [ hasAlreadyRendered, RecursionProvider ] = useNoRecursiveRenders(
Expand Down Expand Up @@ -120,9 +121,10 @@ export default function ReusableBlockEdit( { attributes: { ref }, clientId } ) {
<ToolbarGroup>
<ToolbarButton
onClick={ () => convertBlockToStatic( clientId ) }
>
{ __( 'Convert to regular blocks' ) }
</ToolbarButton>
label={ __( 'Convert to regular blocks' ) }
icon={ ungroup }
showTooltip
/>
</ToolbarGroup>
</BlockControls>
<InspectorControls>
Expand Down
10 changes: 3 additions & 7 deletions packages/e2e-tests/specs/editor/various/reusable-blocks.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,16 +77,12 @@ const createReusableBlock = async ( content, title ) => {
};

describe( 'Reusable blocks', () => {
beforeAll( async () => {
await createNewPost();
} );

afterAll( async () => {
await trashAllPosts( 'wp_block' );
} );

beforeEach( async () => {
await clearAllBlocks();
await createNewPost();
} );

it( 'can be created with no title', async () => {
Expand Down Expand Up @@ -142,7 +138,7 @@ describe( 'Reusable blocks', () => {
await insertReusableBlock( 'Surprised greeting block' );

// Convert block to a regular block
await clickBlockToolbarButton( 'Convert to regular blocks', 'content' );
await clickBlockToolbarButton( 'Convert to regular blocks' );

// Check that we have a paragraph block on the page
const paragraphBlock = await page.$(
Expand Down Expand Up @@ -219,7 +215,7 @@ describe( 'Reusable blocks', () => {
await insertReusableBlock( 'Multi-selection reusable block' );

// Convert block to a regular block
await clickBlockToolbarButton( 'Convert to regular blocks', 'content' );
await clickBlockToolbarButton( 'Convert to regular blocks' );

// Check that we have two paragraph blocks on the page
expect( await getEditedPostContent() ).toMatchSnapshot();
Expand Down
1 change: 1 addition & 0 deletions packages/icons/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ export { default as tool } from './library/tool';
export { default as trash } from './library/trash';
export { default as typography } from './library/typography';
export { default as undo } from './library/undo';
export { default as ungroup } from './library/ungroup';
export { default as update } from './library/update';
export { default as upload } from './library/upload';
export { default as verse } from './library/verse';
Expand Down
12 changes: 12 additions & 0 deletions packages/icons/src/library/ungroup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/**
* WordPress dependencies
*/
import { SVG, Path } from '@wordpress/primitives';

const ungroup = (
<SVG xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<Path d="M18 4h-7c-1.1 0-2 .9-2 2v7c0 1.1.9 2 2 2h7c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm.5 9c0 .3-.2.5-.5.5h-7c-.3 0-.5-.2-.5-.5V6c0-.3.2-.5.5-.5h7c.3 0 .5.2.5.5v7zm-5 5c0 .3-.2.5-.5.5H6c-.3 0-.5-.2-.5-.5v-7c0-.3.2-.5.5-.5h1V9H6c-1.1 0-2 .9-2 2v7c0 1.1.9 2 2 2h7c1.1 0 2-.9 2-2v-1h-1.5v1z" />
</SVG>
);

export default ungroup;