From c17e571ee1a660bd177a8891815596db3ddfd6b9 Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Wed, 10 Apr 2019 16:15:01 +0100 Subject: [PATCH] Experiment with rudity mentory mechanic to allow Block Grouping Tried a few approaches via `insertBlock/removeBlocks` and even `replaceBlocks` but nothing preserved the undo history apart from this rather brute force method. --- .../convert-button.js | 83 +++++++++++++++++++ .../convert-to-group-buttons/index.js | 33 ++++++++ .../editor/src/components/provider/index.js | 2 + 3 files changed, 118 insertions(+) create mode 100644 packages/editor/src/components/convert-to-group-buttons/convert-button.js create mode 100644 packages/editor/src/components/convert-to-group-buttons/index.js diff --git a/packages/editor/src/components/convert-to-group-buttons/convert-button.js b/packages/editor/src/components/convert-to-group-buttons/convert-button.js new file mode 100644 index 0000000000000..b1689b4ef5b9e --- /dev/null +++ b/packages/editor/src/components/convert-to-group-buttons/convert-button.js @@ -0,0 +1,83 @@ +/** + * External dependencies + */ +import { noop } from 'lodash'; + +/** + * WordPress dependencies + */ +import { Fragment } from '@wordpress/element'; +import { MenuItem } from '@wordpress/components'; +import { __ } from '@wordpress/i18n'; +import { createBlock } from '@wordpress/blocks'; +import { withSelect, withDispatch } from '@wordpress/data'; +import { compose } from '@wordpress/compose'; + +export function ConvertToGroupButton( { + onConvertToGroup, +} ) { + return ( + + + { __( 'Convert to Group' ) } + + + ); +} + +export default compose( [ + withSelect( ( select, { clientIds } ) => { + const { + getBlocksByClientId, + getBlockRootClientId, + } = select( 'core/block-editor' ); + + const blocksToGroup = getBlocksByClientId( clientIds ); + + const isGroupable = ( + blocksToGroup.length === 1 && + blocksToGroup[ 0 ] + ); + + // Define any edge cases here + const isVisible = true; + + return { + isGroupable, + isVisible, + blocksToGroup, + getBlockRootClientId, + }; + } ), + withDispatch( ( dispatch, { clientIds, onToggle = noop, blocksToGroup = [], getBlockRootClientId } ) => { + const { + insertBlock, + moveBlockToPosition, + } = dispatch( 'core/block-editor' ); + + return { + onConvertToGroup() { + if ( ! blocksToGroup.length ) { + return; + } + + const wrapperBlock = createBlock( 'core/section', { + backgroundColor: 'lighter-blue', + } ); + + const firstBlockIndex = blocksToGroup[ 0 ].clientId; + + insertBlock( wrapperBlock, firstBlockIndex ); + + clientIds.forEach( ( blockClientId ) => { + moveBlockToPosition( blockClientId, getBlockRootClientId( blockClientId ), wrapperBlock.clientId ); + } ); + onToggle(); + }, + }; + } ), +] )( ConvertToGroupButton ); diff --git a/packages/editor/src/components/convert-to-group-buttons/index.js b/packages/editor/src/components/convert-to-group-buttons/index.js new file mode 100644 index 0000000000000..304da07c5d5a6 --- /dev/null +++ b/packages/editor/src/components/convert-to-group-buttons/index.js @@ -0,0 +1,33 @@ +/** + * WordPress dependencies + */ +import { Fragment } from '@wordpress/element'; +import { __experimentalBlockSettingsMenuPluginsExtension } from '@wordpress/block-editor'; +import { withSelect } from '@wordpress/data'; + +/** + * Internal dependencies + */ +import ConvertToGroupButton from './convert-button'; + +function ReusableBlocksButtons( { clientIds } ) { + return ( + <__experimentalBlockSettingsMenuPluginsExtension> + { ( { onClose } ) => ( + + + + ) } + + ); +} + +export default withSelect( ( select ) => { + const { getSelectedBlockClientIds } = select( 'core/block-editor' ); + return { + clientIds: getSelectedBlockClientIds(), + }; +} )( ReusableBlocksButtons ); diff --git a/packages/editor/src/components/provider/index.js b/packages/editor/src/components/provider/index.js index 54405f61247b8..6a02ebf945d7a 100644 --- a/packages/editor/src/components/provider/index.js +++ b/packages/editor/src/components/provider/index.js @@ -22,6 +22,7 @@ import { decodeEntities } from '@wordpress/html-entities'; import transformStyles from '../../editor-styles'; import { mediaUpload } from '../../utils'; import ReusableBlocksButtons from '../reusable-blocks-buttons'; +import ConvertToGroupButtons from '../convert-to-group-buttons'; const fetchLinkSuggestions = async ( search ) => { const posts = await apiFetch( { @@ -158,6 +159,7 @@ class EditorProvider extends Component { > { children } + ); }