Skip to content

Commit

Permalink
[Block Editor]: Better block transforms organization
Browse files Browse the repository at this point in the history
  • Loading branch information
ntsekouras committed Sep 12, 2022
1 parent 74cd9f9 commit 54d4f63
Showing 1 changed file with 93 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,61 @@ import {
getBlockMenuDefaultClassName,
switchToBlockType,
} from '@wordpress/blocks';
import { useState } from '@wordpress/element';
import { useState, useMemo } from '@wordpress/element';

/**
* Internal dependencies
*/
import BlockIcon from '../block-icon';
import PreviewBlockPopover from './preview-block-popover';

/**
* Helper hook to group transformations to display them in a specific order in the UI.
* For now we group only priority content driven transformations(ex. paragraph -> heading).
*
* Later on we could also group 'layout' transformations(ex. paragraph -> group) and
* display them in different sections.
*
* @param {Object[]} possibleBlockTransformations The available block transformations.
* @return {Record<string, Object[]>} The grouped block transformations.
*/
function useGroupedTransforms( possibleBlockTransformations ) {
const priorityContentTranformationBlocks = {
'core/paragraph': 1,
'core/heading': 2,
'core/list': 3,
'core/quote': 4,
};
const transformations = useMemo( () => {
const priorityTextTranformsNames = Object.keys(
priorityContentTranformationBlocks
);
return possibleBlockTransformations.reduce(
( accumulator, item ) => {
const { name } = item;
if ( priorityTextTranformsNames.includes( name ) ) {
accumulator.priorityTextTransformations.push( item );
} else {
accumulator.restTransformations.push( item );
}
return accumulator;
},
{ priorityTextTransformations: [], restTransformations: [] }
);
}, [ possibleBlockTransformations ] );

// Order the priority text transformations.
transformations.priorityTextTransformations.sort(
( { name: currentName }, { name: nextName } ) => {
return priorityContentTranformationBlocks[ currentName ] <
priorityContentTranformationBlocks[ nextName ]
? -1
: 1;
}
);
return transformations;
}

const BlockTransformationsMenu = ( {
className,
possibleBlockTransformations,
Expand All @@ -23,6 +70,11 @@ const BlockTransformationsMenu = ( {
} ) => {
const [ hoveredTransformItemName, setHoveredTransformItemName ] =
useState();

const { priorityTextTransformations, restTransformations } =
useGroupedTransforms( possibleBlockTransformations );
const needsTextTransformationsSeparator =
priorityTextTransformations.length && restTransformations.length;
return (
<MenuGroup label={ __( 'Transform to' ) } className={ className }>
{ hoveredTransformItemName && (
Expand All @@ -33,31 +85,48 @@ const BlockTransformationsMenu = ( {
) }
/>
) }
{ possibleBlockTransformations.map( ( item ) => {
const { name, icon, title, isDisabled } = item;
return (
<MenuItem
key={ name }
className={ getBlockMenuDefaultClassName( name ) }
onClick={ ( event ) => {
event.preventDefault();
onSelect( name );
} }
disabled={ isDisabled }
onMouseLeave={ () =>
setHoveredTransformItemName( null )
}
onMouseEnter={ () =>
setHoveredTransformItemName( name )
}
>
<BlockIcon icon={ icon } showColors />
{ title }
</MenuItem>
);
} ) }
{ priorityTextTransformations.map( ( item ) => (
<BlockTranformationItem
key={ item.name }
item={ item }
onSelect={ onSelect }
setHoveredTransformItemName={ setHoveredTransformItemName }
/>
) ) }
{ !! needsTextTransformationsSeparator && <hr /> }
{ restTransformations.map( ( item ) => (
<BlockTranformationItem
key={ item.name }
item={ item }
onSelect={ onSelect }
setHoveredTransformItemName={ setHoveredTransformItemName }
/>
) ) }
</MenuGroup>
);
};

function BlockTranformationItem( {
item,
onSelect,
setHoveredTransformItemName,
} ) {
const { name, icon, title, isDisabled } = item;
return (
<MenuItem
className={ getBlockMenuDefaultClassName( name ) }
onClick={ ( event ) => {
event.preventDefault();
onSelect( name );
} }
disabled={ isDisabled }
onMouseLeave={ () => setHoveredTransformItemName( null ) }
onMouseEnter={ () => setHoveredTransformItemName( name ) }
>
<BlockIcon icon={ icon } showColors />
{ title }
</MenuItem>
);
}

export default BlockTransformationsMenu;

0 comments on commit 54d4f63

Please sign in to comment.