Skip to content

Commit

Permalink
[RNMobile] Add Group and Ungroup block actions (#50693)
Browse files Browse the repository at this point in the history
* Add `useConvertToGroupButtons` hook

Most of the logic of this hook has been extracted from `ConvertToGroupButton` component. The main difference is that we return the configuration for the block actions instead of a component.

* Add Group and Ungroup options to block actions menu

* Remove `canUnwrap` option from `getBlockTransformOptions` test helper

* Update tests for Group, Quote and Columns blocks
  • Loading branch information
fluiddot authored May 19, 2023
1 parent 7bbf8cc commit 5c6d77b
Show file tree
Hide file tree
Showing 9 changed files with 120 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ import { store as coreStore } from '@wordpress/core-data';
import { getMoversSetup } from '../block-mover/mover-description';
import { store as blockEditorStore } from '../../store';
import BlockTransformationsMenu from '../block-switcher/block-transformations-menu';
import {
useConvertToGroupButtons,
useConvertToGroupButtonProps,
} from '../convert-to-group-buttons';

const BlockActionsMenu = ( {
// Select.
Expand All @@ -55,6 +59,7 @@ const BlockActionsMenu = ( {
rootClientId,
selectedBlockClientId,
selectedBlockPossibleTransformations,
canRemove,
// Dispatch.
createSuccessNotice,
convertToRegularBlocks,
Expand Down Expand Up @@ -93,6 +98,17 @@ const BlockActionsMenu = ( {
},
} = getMoversSetup( isStackedHorizontally, moversOptions );

// Check if selected block is Groupable and/or Ungroupable.
const convertToGroupButtonProps = useConvertToGroupButtonProps( [
selectedBlockClientId,
] );
const { isGroupable, isUngroupable } = convertToGroupButtonProps;
const showConvertToGroupButton =
( isGroupable || isUngroupable ) && canRemove;
const convertToGroupButtons = useConvertToGroupButtons( {
...convertToGroupButtonProps,
} );

const allOptions = {
settings: {
id: 'settingsOption',
Expand Down Expand Up @@ -229,6 +245,10 @@ const BlockActionsMenu = ( {
canDuplicate && allOptions.cutButton,
canDuplicate && isPasteEnabled && allOptions.pasteButton,
canDuplicate && allOptions.duplicateButton,
showConvertToGroupButton && isGroupable && convertToGroupButtons.group,
showConvertToGroupButton &&
isUngroupable &&
convertToGroupButtons.ungroup,
isReusableBlockType &&
innerBlockCount > 0 &&
allOptions.convertToRegularBlocks,
Expand Down Expand Up @@ -327,6 +347,7 @@ export default compose(
getSelectedBlockClientIds,
canInsertBlockType,
getTemplateLock,
canRemoveBlock,
} = select( blockEditorStore );
const block = getBlock( clientId );
const blockName = getBlockName( clientId );
Expand Down Expand Up @@ -363,6 +384,7 @@ export default compose(
const selectedBlockPossibleTransformations = selectedBlock
? getBlockTransformItems( selectedBlock, rootClientId )
: EMPTY_BLOCK_LIST;
const canRemove = canRemoveBlock( selectedBlockClientId );

const isReusableBlockType = block ? isReusableBlock( block ) : false;
const reusableBlock = isReusableBlockType
Expand All @@ -388,6 +410,7 @@ export default compose(
rootClientId,
selectedBlockClientId,
selectedBlockPossibleTransformations,
canRemove,
};
} ),
withDispatch(
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1,79 @@
export default () => null;
/**
* WordPress dependencies
*/
import { __, _x } from '@wordpress/i18n';
import { switchToBlockType } from '@wordpress/blocks';
import { useDispatch } from '@wordpress/data';
import { store as noticesStore } from '@wordpress/notices';

/**
* Internal dependencies
*/
import { store as blockEditorStore } from '../../store';
import useConvertToGroupButtonProps from './use-convert-to-group-button-props';

function useConvertToGroupButtons( {
clientIds,
onUngroup,
blocksSelection,
groupingBlockName,
} ) {
const { replaceBlocks } = useDispatch( blockEditorStore );
const { createSuccessNotice } = useDispatch( noticesStore );
const onConvertToGroup = () => {
// Activate the `transform` on the Grouping Block which does the conversion.
const newBlocks = switchToBlockType(
blocksSelection,
groupingBlockName
);
if ( newBlocks ) {
replaceBlocks( clientIds, newBlocks );
}
};

const onConvertFromGroup = () => {
let innerBlocks = blocksSelection[ 0 ].innerBlocks;
if ( ! innerBlocks.length ) {
return;
}
if ( onUngroup ) {
innerBlocks = onUngroup(
blocksSelection[ 0 ].attributes,
blocksSelection[ 0 ].innerBlocks
);
}
replaceBlocks( clientIds, innerBlocks );
};

return {
group: {
id: 'groupButtonOption',
label: _x( 'Group', 'verb' ),
value: 'groupButtonOption',
onSelect: () => {
onConvertToGroup();
createSuccessNotice(
// translators: displayed right after the block is grouped
__( 'Block grouped' )
);
},
},
ungroup: {
id: 'ungroupButtonOption',
label: _x(
'Ungroup',
'Ungrouping blocks from within a grouping block back into individual blocks within the Editor'
),
value: 'ungroupButtonOption',
onSelect: () => {
onConvertFromGroup();
createSuccessNotice(
// translators: displayed right after the block is ungrouped.
__( 'Block ungrouped' )
);
},
},
};
}

export { useConvertToGroupButtons, useConvertToGroupButtonProps };
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ exports[`Columns block transforms to Group block 1`] = `
<!-- /wp:group -->"
`;

exports[`Columns block transforms unwraps content 1`] = `
exports[`Columns block transforms ungroups block 1`] = `
"<!-- wp:paragraph {"align":"left"} -->
<p class="has-text-align-left"><strong>Built with modern technology.</strong></p>
<!-- /wp:paragraph -->
Expand Down
8 changes: 3 additions & 5 deletions packages/block-library/src/columns/test/transforms.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,13 @@ describe( `${ block } block transforms`, () => {
expect( getEditorHtml() ).toMatchSnapshot();
} );

it( 'unwraps content', async () => {
it( 'ungroups block', async () => {
const screen = await initializeEditor( { initialHtml } );
const { getByText } = screen;
fireEvent.press( getBlock( screen, block ) );

await openBlockActionsMenu( screen );
fireEvent.press( getByText( 'Transform block…' ) );
fireEvent.press( getByText( 'Unwrap' ) );
fireEvent.press( getByText( 'Ungroup' ) );

// The first block created is the content of the Paragraph block.
const paragraph = getBlock( screen, 'Paragraph', 0 );
Expand All @@ -83,8 +82,7 @@ describe( `${ block } block transforms`, () => {
const screen = await initializeEditor( { initialHtml } );
const transformOptions = await getBlockTransformOptions(
screen,
block,
{ canUnwrap: true }
block
);
expect( transformOptions ).toHaveLength( blockTransforms.length );
} );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ exports[`Group block transforms to Columns block 1`] = `
<!-- /wp:columns -->"
`;

exports[`Group block transforms unwraps content 1`] = `
exports[`Group block transforms ungroups block 1`] = `
"<!-- wp:paragraph -->
<p>One.</p>
<!-- /wp:paragraph -->
Expand Down
8 changes: 3 additions & 5 deletions packages/block-library/src/group/test/transforms.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,13 @@ describe( `${ block } block transforms`, () => {
expect( getEditorHtml() ).toMatchSnapshot();
} );

it( 'unwraps content', async () => {
it( 'ungroups block', async () => {
const screen = await initializeEditor( { initialHtml } );
const { getByText } = screen;
fireEvent.press( getBlock( screen, block ) );

await openBlockActionsMenu( screen );
fireEvent.press( getByText( 'Transform block…' ) );
fireEvent.press( getByText( 'Unwrap' ) );
fireEvent.press( getByText( 'Ungroup' ) );

// The first block created is the content of the Paragraph block.
const paragraph = getBlock( screen, 'Paragraph', 0 );
Expand All @@ -67,8 +66,7 @@ describe( `${ block } block transforms`, () => {
const screen = await initializeEditor( { initialHtml } );
const transformOptions = await getBlockTransformOptions(
screen,
block,
{ canUnwrap: true }
block
);
expect( transformOptions ).toHaveLength( blockTransforms.length );
} );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ exports[`Quote block transforms to Pullquote block 1`] = `
<!-- /wp:pullquote -->"
`;

exports[`Quote block transforms unwraps content 1`] = `
exports[`Quote block transforms ungroups block 1`] = `
"<!-- wp:paragraph -->
<p>"This will make running your own blog a viable alternative again."</p>
<!-- /wp:paragraph -->
Expand Down
8 changes: 3 additions & 5 deletions packages/block-library/src/quote/test/transforms.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,13 @@ describe( `${ block } block transforms`, () => {
expect( getEditorHtml() ).toMatchSnapshot();
} );

it( 'unwraps content', async () => {
it( 'ungroups block', async () => {
const screen = await initializeEditor( { initialHtml } );
const { getByText } = screen;
fireEvent.press( getBlock( screen, block ) );

await openBlockActionsMenu( screen );
fireEvent.press( getByText( 'Transform block…' ) );
fireEvent.press( getByText( 'Unwrap' ) );
fireEvent.press( getByText( 'Ungroup' ) );

// The first block created is the content of the Paragraph block.
const paragraph = getBlock( screen, 'Paragraph', 0 );
Expand All @@ -59,8 +58,7 @@ describe( `${ block } block transforms`, () => {
const screen = await initializeEditor( { initialHtml } );
const transformOptions = await getBlockTransformOptions(
screen,
block,
{ canUnwrap: true }
block
);
expect( transformOptions ).toHaveLength( blockTransforms.length );
} );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,36 +12,18 @@ import { openBlockActionsMenu } from './open-block-actions-menu';
/**
* Transforms the selected block to a specified block.
*
* @param {import('@testing-library/react-native').RenderAPI} screen A Testing Library screen.
* @param {string} blockName Name of the block.
* @param {Object} [options] Configuration options.
* @param {number} [options.canUnwrap] True if the block can be unwrapped.
* @param {import('@testing-library/react-native').RenderAPI} screen A Testing Library screen.
* @param {string} blockName Name of the block.
* @return {[import('react-test-renderer').ReactTestInstance]} Block transform options.
*/
export const getBlockTransformOptions = async (
screen,
blockName,
{ canUnwrap = false } = {}
) => {
export const getBlockTransformOptions = async ( screen, blockName ) => {
const { getByTestId, getByText } = screen;

fireEvent.press( getBlock( screen, blockName ) );
await openBlockActionsMenu( screen );
fireEvent.press( getByText( 'Transform block…' ) );

let blockTransformButtons = within(
getByTestId( 'block-transformations-menu' )
).getAllByRole( 'button' );

// Remove Unwrap option as it's not a direct block transformation.
if ( canUnwrap ) {
const unwrapButton = within(
getByTestId( 'block-transformations-menu' )
).getByLabelText( 'Unwrap' );
blockTransformButtons = blockTransformButtons.filter(
( button ) => button !== unwrapButton
);
}

return blockTransformButtons;
return within( getByTestId( 'block-transformations-menu' ) ).getAllByRole(
'button'
);
};

0 comments on commit 5c6d77b

Please sign in to comment.