diff --git a/packages/block-editor/src/components/block-variation-transforms/index.js b/packages/block-editor/src/components/block-variation-transforms/index.js index bcb1ccb5bd6374..b8099e46c025b0 100644 --- a/packages/block-editor/src/components/block-variation-transforms/index.js +++ b/packages/block-editor/src/components/block-variation-transforms/index.js @@ -2,47 +2,63 @@ * WordPress dependencies */ import { store as blocksStore } from '@wordpress/blocks'; -import { __ } from '@wordpress/i18n'; +import { __, sprintf } from '@wordpress/i18n'; import { + Button, DropdownMenu, MenuGroup, MenuItemsChoice, + VisuallyHidden, } from '@wordpress/components'; import { useSelect, useDispatch } from '@wordpress/data'; -import { useState, useEffect } from '@wordpress/element'; +import { useMemo } from '@wordpress/element'; import { chevronDown } from '@wordpress/icons'; /** * Internal dependencies */ -import { __experimentalGetMatchingVariation as getMatchingVariation } from '../../utils'; import { store as blockEditorStore } from '../../store'; -function __experimentalBlockVariationTransforms( { blockClientId } ) { - const [ selectedValue, setSelectedValue ] = useState(); - const { updateBlockAttributes } = useDispatch( blockEditorStore ); - const { variations, blockAttributes } = useSelect( - ( select ) => { - const { getBlockVariations } = select( blocksStore ); - const { getBlockName, getBlockAttributes } = select( - blockEditorStore - ); - const blockName = blockClientId && getBlockName( blockClientId ); - return { - variations: - blockName && getBlockVariations( blockName, 'transform' ), - blockAttributes: getBlockAttributes( blockClientId ), - }; - }, - [ blockClientId ] +function VariationsButtons( { + className, + onSelectVariation, + selectedValue, + variations, +} ) { + return ( +
+ + { __( 'Transform to variation' ) } + + { variations.map( ( variation ) => ( +
); - useEffect( () => { - setSelectedValue( - getMatchingVariation( blockAttributes, variations )?.name - ); - }, [ blockAttributes, variations ] ); - if ( ! variations?.length ) return null; +} +function VariationsDropdown( { + className, + onSelectVariation, + selectedValue, + variations, +} ) { const selectOptions = variations.map( ( { name, title, description } ) => ( { value: name, @@ -50,27 +66,21 @@ function __experimentalBlockVariationTransforms( { blockClientId } ) { info: description, } ) ); - const onSelectVariation = ( variationName ) => { - updateBlockAttributes( blockClientId, { - ...variations.find( ( { name } ) => name === variationName ) - .attributes, - } ); - }; - const baseClass = 'block-editor-block-variation-transforms'; + return ( { () => ( -
+
{ + const { getActiveBlockVariation, getBlockVariations } = select( + blocksStore + ); + const { getBlockName, getBlockAttributes } = select( + blockEditorStore + ); + const name = blockClientId && getBlockName( blockClientId ); + return { + activeBlockVariation: getActiveBlockVariation( + name, + getBlockAttributes( blockClientId ) + ), + variations: name && getBlockVariations( name, 'transform' ), + }; + }, + [ blockClientId ] + ); + + const selectedValue = activeBlockVariation?.name; + + // Check if each variation has a unique icon. + const hasUniqueIcons = useMemo( () => { + const variationIcons = new Set(); + variations.forEach( ( variation ) => { + if ( variation.icon ) { + variationIcons.add( variation.icon ); + } + } ); + return variationIcons.size === variations.length; + }, [ variations ] ); + + const onSelectVariation = ( variationName ) => { + updateBlockAttributes( blockClientId, { + ...variations.find( ( { name } ) => name === variationName ) + .attributes, + } ); + }; + + const baseClass = 'block-editor-block-variation-transforms'; + + // Skip rendering if there are no variations + if ( ! variations?.length ) return null; + + const Component = hasUniqueIcons ? VariationsButtons : VariationsDropdown; + + return ( + + ); +} + export default __experimentalBlockVariationTransforms; diff --git a/packages/block-editor/src/components/block-variation-transforms/style.scss b/packages/block-editor/src/components/block-variation-transforms/style.scss index 2a02afdf6b7476..b828bc6020bfbe 100644 --- a/packages/block-editor/src/components/block-variation-transforms/style.scss +++ b/packages/block-editor/src/components/block-variation-transforms/style.scss @@ -1,5 +1,5 @@ .block-editor-block-variation-transforms { - padding: 0 $grid-unit-20 $grid-unit-20 56px; + padding: 0 $grid-unit-20 $grid-unit-20 52px; width: 100%; .components-dropdown-menu__toggle { diff --git a/packages/block-library/src/group/variations.js b/packages/block-library/src/group/variations.js index 047c08b881d148..76c366ec7f23dd 100644 --- a/packages/block-library/src/group/variations.js +++ b/packages/block-library/src/group/variations.js @@ -2,7 +2,7 @@ * WordPress dependencies */ import { __ } from '@wordpress/i18n'; -import { row, stack } from '@wordpress/icons'; +import { group, row, stack } from '@wordpress/icons'; const variations = [ { @@ -14,6 +14,7 @@ const variations = [ isActive: ( blockAttributes ) => ! blockAttributes.layout || blockAttributes.layout?.type === 'default', + icon: group, }, { name: 'group-row',