-
Notifications
You must be signed in to change notification settings - Fork 4.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Block variations transformations (#26687)
* __experimentalBlockVariationTransforms first iteration * some small fixes * test with Navigation variations * Update docs/designers-developers/developers/block-api/block-registration.md Co-authored-by: Greg Ziółkowski <grzegorz@gziolo.pl> * move navigation variations to its own file * doc scope options * change getBlockVariations + add tests * change doc for scope * change selector implementation * add readme * minor changes * remove test * simplify API by passing only client id * change design to DropdownMenu * remove obsolete spread * rename prop * polish styles * add variation matcher for attributes only * iconPosition doc + change * make matcher to return only name * getMatchingVariationName change to array.filter + unit tests Co-authored-by: Greg Ziółkowski <grzegorz@gziolo.pl>
- Loading branch information
1 parent
80e30fd
commit 0b9b34f
Showing
18 changed files
with
401 additions
and
75 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
54 changes: 54 additions & 0 deletions
54
packages/block-editor/src/components/block-variation-transforms/README.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
# Block Variation Transforms | ||
|
||
This component allows to display the selected block's variations which have the `transform` option set in `scope` property and to choose one of them. | ||
|
||
By selecting such a variation an update to the selected block's attributes happen, based on the variation's attributes. | ||
|
||
## Table of contents | ||
|
||
1. [Development guidelines](#development-guidelines) | ||
2. [Related components](#related-components) | ||
|
||
## Development guidelines | ||
|
||
### Usage | ||
|
||
Renders the block's variations which have the `transform` option set in `scope` property. | ||
|
||
```jsx | ||
import { useSelect } from '@wordpress/data'; | ||
import { | ||
__experimentalBlockVariationTransforms as BlockVariationTransforms, | ||
} from '@wordpress/block-editor'; | ||
|
||
const MyBlockVariationTransforms = () => { | ||
const { selectedBlockClientId } = useSelect( | ||
( select ) => { | ||
const { getSelectedBlockClientId } = select( | ||
'core/block-editor' | ||
); | ||
return { | ||
selectedBlockClientId: getSelectedBlockClientId(), | ||
}; | ||
} | ||
); | ||
|
||
return ( | ||
<BlockVariationTransforms | ||
blockClientId={ selectedBlockClientId } | ||
/> | ||
); | ||
}; | ||
``` | ||
|
||
### Props | ||
|
||
#### blockClientId | ||
|
||
The block's client id. | ||
|
||
- Type: `string` | ||
|
||
## Related components | ||
|
||
Block Editor components are components that can be used to compose the UI of your block editor. Thus, they can only be used under a [BlockEditorProvider](https://github.com/WordPress/gutenberg/blob/master/packages/block-editor/src/components/provider/README.md) in the components tree. |
95 changes: 95 additions & 0 deletions
95
packages/block-editor/src/components/block-variation-transforms/index.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
import { isMatch } from 'lodash'; | ||
|
||
/** | ||
* WordPress dependencies | ||
*/ | ||
import { __ } from '@wordpress/i18n'; | ||
import { | ||
DropdownMenu, | ||
MenuGroup, | ||
MenuItemsChoice, | ||
} from '@wordpress/components'; | ||
import { useSelect, useDispatch } from '@wordpress/data'; | ||
import { useState, useEffect } from '@wordpress/element'; | ||
import { chevronDown } from '@wordpress/icons'; | ||
|
||
export const getMatchingVariationName = ( blockAttributes, variations ) => { | ||
if ( ! variations || ! blockAttributes ) return; | ||
const matches = variations.filter( ( { attributes } ) => { | ||
if ( ! attributes || ! Object.keys( attributes ).length ) return false; | ||
return isMatch( blockAttributes, attributes ); | ||
} ); | ||
if ( matches.length !== 1 ) return; | ||
return matches[ 0 ].name; | ||
}; | ||
|
||
function __experimentalBlockVariationTransforms( { blockClientId } ) { | ||
const [ selectedValue, setSelectedValue ] = useState(); | ||
const { updateBlockAttributes } = useDispatch( 'core/block-editor' ); | ||
const { variations, blockAttributes } = useSelect( | ||
( select ) => { | ||
const { getBlockVariations } = select( 'core/blocks' ); | ||
const { getBlockName, getBlockAttributes } = select( | ||
'core/block-editor' | ||
); | ||
const blockName = blockClientId && getBlockName( blockClientId ); | ||
return { | ||
variations: | ||
blockName && getBlockVariations( blockName, 'transform' ), | ||
blockAttributes: getBlockAttributes( blockClientId ), | ||
}; | ||
}, | ||
[ blockClientId ] | ||
); | ||
useEffect( () => { | ||
setSelectedValue( | ||
getMatchingVariationName( blockAttributes, variations ) | ||
); | ||
}, [ blockAttributes, variations ] ); | ||
if ( ! variations?.length ) return null; | ||
|
||
const selectOptions = variations.map( | ||
( { name, title, description } ) => ( { | ||
value: name, | ||
label: title, | ||
info: description, | ||
} ) | ||
); | ||
const onSelectVariation = ( variationName ) => { | ||
updateBlockAttributes( blockClientId, { | ||
...variations.find( ( { name } ) => name === variationName ) | ||
.attributes, | ||
} ); | ||
}; | ||
const baseClass = 'block-editor-block-variation-transforms'; | ||
return ( | ||
<DropdownMenu | ||
className={ baseClass } | ||
label={ __( 'Transform to variation' ) } | ||
text={ __( 'Transform to variation' ) } | ||
popoverProps={ { | ||
position: 'bottom center', | ||
className: `${ baseClass }__popover`, | ||
} } | ||
icon={ chevronDown } | ||
toggleProps={ { iconPosition: 'right' } } | ||
> | ||
{ () => ( | ||
<div className={ `${ baseClass }__container` }> | ||
<MenuGroup> | ||
<MenuItemsChoice | ||
choices={ selectOptions } | ||
value={ selectedValue } | ||
onSelect={ onSelectVariation } | ||
/> | ||
</MenuGroup> | ||
</div> | ||
) } | ||
</DropdownMenu> | ||
); | ||
} | ||
|
||
export default __experimentalBlockVariationTransforms; |
38 changes: 38 additions & 0 deletions
38
packages/block-editor/src/components/block-variation-transforms/style.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
.block-editor-block-variation-transforms { | ||
padding: 0 $grid-unit-20 $grid-unit-20 56px; | ||
width: 100%; | ||
|
||
.components-dropdown-menu__toggle { | ||
border: 1px solid $gray-700; | ||
border-radius: $radius-block-ui; | ||
min-height: 30px; | ||
width: 100%; | ||
position: relative; | ||
text-align: left; | ||
justify-content: left; | ||
padding: 6px 12px; | ||
|
||
// For all button sizes allow sufficient space for the | ||
// dropdown "arrow" icon to display. | ||
&.components-dropdown-menu__toggle { | ||
padding-right: $icon-size; | ||
} | ||
|
||
&:focus:not(:disabled) { | ||
border-color: var(--wp-admin-theme-color); | ||
box-shadow: 0 0 0 ($border-width-focus - $border-width) var(--wp-admin-theme-color); | ||
} | ||
|
||
svg { | ||
height: 100%; | ||
padding: 0; | ||
position: absolute; | ||
right: 0; | ||
top: 0; | ||
} | ||
} | ||
} | ||
|
||
.block-editor-block-variation-transforms__popover .components-popover__content { | ||
min-width: 230px; | ||
} |
75 changes: 75 additions & 0 deletions
75
packages/block-editor/src/components/block-variation-transforms/test/index.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
/** | ||
* Internal dependencies | ||
*/ | ||
import { getMatchingVariationName } from '../index'; | ||
|
||
describe( 'BlockVariationTransforms', () => { | ||
describe( 'getMatchingVariationName', () => { | ||
describe( 'should not find a match', () => { | ||
it( 'when no variations or attributes passed', () => { | ||
expect( | ||
getMatchingVariationName( null, { content: 'hi' } ) | ||
).toBeUndefined(); | ||
expect( getMatchingVariationName( {} ) ).toBeUndefined(); | ||
} ); | ||
it( 'when no variation matched', () => { | ||
const variations = [ | ||
{ name: 'one', attributes: { level: 1 } }, | ||
{ name: 'two', attributes: { level: 2 } }, | ||
]; | ||
expect( | ||
getMatchingVariationName( { level: 4 }, variations ) | ||
).toBeUndefined(); | ||
} ); | ||
it( 'when more than one match found', () => { | ||
const variations = [ | ||
{ name: 'one', attributes: { level: 1 } }, | ||
{ name: 'two', attributes: { level: 1, content: 'hi' } }, | ||
]; | ||
expect( | ||
getMatchingVariationName( | ||
{ level: 1, content: 'hi', other: 'prop' }, | ||
variations | ||
) | ||
).toBeUndefined(); | ||
} ); | ||
it( 'when variation is a superset of attributes', () => { | ||
const variations = [ | ||
{ name: 'one', attributes: { level: 1, content: 'hi' } }, | ||
]; | ||
expect( | ||
getMatchingVariationName( | ||
{ level: 1, other: 'prop' }, | ||
variations | ||
) | ||
).toBeUndefined(); | ||
} ); | ||
} ); | ||
describe( 'should find a match', () => { | ||
it( 'when variation has one attribute', () => { | ||
const variations = [ | ||
{ name: 'one', attributes: { level: 1 } }, | ||
{ name: 'two', attributes: { level: 2 } }, | ||
]; | ||
expect( | ||
getMatchingVariationName( | ||
{ level: 2, content: 'hi', other: 'prop' }, | ||
variations | ||
) | ||
).toEqual( 'two' ); | ||
} ); | ||
it( 'when variation has many attributes', () => { | ||
const variations = [ | ||
{ name: 'one', attributes: { level: 1, content: 'hi' } }, | ||
{ name: 'two', attributes: { level: 2 } }, | ||
]; | ||
expect( | ||
getMatchingVariationName( | ||
{ level: 1, content: 'hi', other: 'prop' }, | ||
variations | ||
) | ||
).toEqual( 'one' ); | ||
} ); | ||
} ); | ||
} ); | ||
} ); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.