Skip to content

Commit

Permalink
Add block variations transformation in block switcher
Browse files Browse the repository at this point in the history
  • Loading branch information
ntsekouras committed Apr 27, 2023
1 parent f2e5491 commit c212e2c
Show file tree
Hide file tree
Showing 2 changed files with 156 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
/**
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
import { MenuGroup, MenuItem } from '@wordpress/components';
import {
getBlockMenuDefaultClassName,
cloneBlock,
store as blocksStore,
} from '@wordpress/blocks';
import { useSelect } from '@wordpress/data';
import { useState, useMemo } from '@wordpress/element';

/**
* Internal dependencies
*/
import { store as blockEditorStore } from '../../store';
import BlockIcon from '../block-icon';
import PreviewBlockPopover from './preview-block-popover';

export function useBlockVariationTransforms( { clientIds, blocks } ) {
const { activeBlockVariation, blockVariationTransformations } = useSelect(
( select ) => {
const {
getBlockRootClientId,
getBlockAttributes,
canRemoveBlocks,
} = select( blockEditorStore );
const { getActiveBlockVariation, getBlockVariations } =
select( blocksStore );
const rootClientId = getBlockRootClientId(
Array.isArray( clientIds ) ? clientIds[ 0 ] : clientIds
);
const canRemove = canRemoveBlocks( clientIds, rootClientId );
// Only handle single selected blocks for now.
if ( blocks.length !== 1 || ! canRemove ) {
return;
}
const [ firstBlock ] = blocks;
return {
blockVariationTransformations: getBlockVariations(
firstBlock.name,
'transform'
),
activeBlockVariation: getActiveBlockVariation(
firstBlock.name,
getBlockAttributes( firstBlock.clientId )
),
};
},
[ clientIds, blocks ]
);
const transformations = useMemo( () => {
return blockVariationTransformations?.filter(
( { name } ) => name !== activeBlockVariation?.name
);
}, [ blockVariationTransformations, activeBlockVariation ] );
return transformations;
}

const BlockVariationTransformationsMenu = ( {
transformations,
onSelect,
blocks,
} ) => {
const [ hoveredTransformItemName, setHoveredTransformItemName ] =
useState();
return (
<MenuGroup label={ __( 'Variations' ) }>
{ hoveredTransformItemName && (
<PreviewBlockPopover
blocks={ cloneBlock(
blocks[ 0 ],
transformations.find(
( { name } ) => name === hoveredTransformItemName
).attributes
) }
/>
) }
{ transformations?.map( ( item ) => (
<BlockVariationTranformationItem
key={ item.name }
item={ item }
onSelect={ onSelect }
setHoveredTransformItemName={ setHoveredTransformItemName }
/>
) ) }
</MenuGroup>
);
};

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

export default BlockVariationTransformationsMenu;
45 changes: 42 additions & 3 deletions packages/block-editor/src/components/block-switcher/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,17 @@ import { store as blockEditorStore } from '../../store';
import useBlockDisplayInformation from '../use-block-display-information';
import BlockIcon from '../block-icon';
import BlockTransformationsMenu from './block-transformations-menu';
import {
useBlockVariationTransforms,
default as BlockVariationTransformationsMenu,
} from './block-variation-transformations-menu';
import BlockStylesMenu from './block-styles-menu';
import PatternTransformationsMenu from './pattern-transformations-menu';
import useBlockDisplayTitle from '../block-title/use-block-display-title';

export const BlockSwitcherDropdownMenu = ( { clientIds, blocks } ) => {
const { replaceBlocks, multiSelect } = useDispatch( blockEditorStore );
const { replaceBlocks, multiSelect, updateBlockAttributes } =
useDispatch( blockEditorStore );
const blockInformation = useBlockDisplayInformation( blocks[ 0 ].clientId );
const {
possibleBlockTransformations,
Expand All @@ -43,9 +48,9 @@ export const BlockSwitcherDropdownMenu = ( { clientIds, blocks } ) => {
getBlockRootClientId,
getBlockTransformItems,
__experimentalGetPatternTransformItems,
canRemoveBlocks,
} = select( blockEditorStore );
const { getBlockStyles, getBlockType } = select( blocksStore );
const { canRemoveBlocks } = select( blockEditorStore );
const rootClientId = getBlockRootClientId(
Array.isArray( clientIds ) ? clientIds[ 0 ] : clientIds
);
Expand Down Expand Up @@ -82,6 +87,11 @@ export const BlockSwitcherDropdownMenu = ( { clientIds, blocks } ) => {
[ clientIds, blocks, blockInformation?.icon ]
);

const blockVariationTransformations = useBlockVariationTransforms( {
clientIds,
blocks,
} );

const blockTitle = useBlockDisplayTitle( {
clientId: Array.isArray( clientIds ) ? clientIds[ 0 ] : clientIds,
maximumLength: 35,
Expand All @@ -105,6 +115,14 @@ export const BlockSwitcherDropdownMenu = ( { clientIds, blocks } ) => {
selectForMultipleBlocks( newBlocks );
}

function onBlockVariationTransform( name ) {
updateBlockAttributes( blocks[ 0 ].clientId, {
...blockVariationTransformations.find(
( { name: variationName } ) => variationName === name
).attributes,
} );
}

// Pattern transformation through the `Patterns` API.
function onPatternTransform( transformedBlocks ) {
replaceBlocks( clientIds, transformedBlocks );
Expand All @@ -118,8 +136,14 @@ export const BlockSwitcherDropdownMenu = ( { clientIds, blocks } ) => {
*/
const hasPossibleBlockTransformations =
!! possibleBlockTransformations.length && canRemove && ! isTemplate;
const hasPossibleBlockVariationTransformations =
!! blockVariationTransformations?.length;
const hasPatternTransformation = !! patterns?.length && canRemove;
if ( ! hasBlockStyles && ! hasPossibleBlockTransformations ) {
if (
! hasBlockStyles &&
! hasPossibleBlockTransformations &&
! hasPossibleBlockVariationTransformations
) {
return (
<ToolbarGroup>
<ToolbarButton
Expand Down Expand Up @@ -163,6 +187,7 @@ export const BlockSwitcherDropdownMenu = ( { clientIds, blocks } ) => {
const showDropDown =
hasBlockStyles ||
hasPossibleBlockTransformations ||
hasPossibleBlockVariationTransformations ||
hasPatternTransformation;
return (
<ToolbarGroup>
Expand Down Expand Up @@ -226,6 +251,20 @@ export const BlockSwitcherDropdownMenu = ( { clientIds, blocks } ) => {
} }
/>
) }
{ hasPossibleBlockVariationTransformations && (
<BlockVariationTransformationsMenu
transformations={
blockVariationTransformations
}
blocks={ blocks }
onSelect={ ( name ) => {
onBlockVariationTransform(
name
);
onClose();
} }
/>
) }
{ hasBlockStyles && (
<BlockStylesMenu
hoveredBlock={ blocks[ 0 ] }
Expand Down

0 comments on commit c212e2c

Please sign in to comment.