Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use a modal for the reusable blocks creation flow #29040

Merged
merged 6 commits into from
Feb 18, 2021
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions lib/client-assets.php
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ function gutenberg_register_packages_styles( $styles ) {
$styles,
'wp-editor',
gutenberg_url( 'build/editor/style.css' ),
array( 'wp-components', 'wp-block-editor', 'wp-nux' ),
array( 'wp-components', 'wp-block-editor', 'wp-nux', 'wp-reusable-blocks' ),
filemtime( gutenberg_dir_path() . 'build/editor/style.css' )
);
$styles->add_data( 'wp-editor', 'rtl', 'replace' );
Expand Down Expand Up @@ -375,6 +375,7 @@ function gutenberg_register_packages_styles( $styles ) {
'wp-components',
'wp-editor',
'wp-block-library',
'wp-reusable-blocks',
// Always include visual styles so the editor never appears broken.
'wp-block-library-theme',
),
Expand Down Expand Up @@ -431,7 +432,7 @@ function gutenberg_register_packages_styles( $styles ) {
$styles,
'wp-edit-widgets',
gutenberg_url( 'build/edit-widgets/style.css' ),
array( 'wp-components', 'wp-block-editor', 'wp-edit-blocks' ),
array( 'wp-components', 'wp-block-editor', 'wp-edit-blocks', 'wp-reusable-blocks' ),
filemtime( gutenberg_dir_path() . 'build/edit-widgets/style.css' )
);
$styles->add_data( 'wp-edit-widgets', 'rtl', 'replace' );
Expand All @@ -453,6 +454,15 @@ function gutenberg_register_packages_styles( $styles ) {
filemtime( gutenberg_dir_path() . 'build/customize-widgets/style.css' )
);
$styles->add_data( 'wp-customize-widgets', 'rtl', 'replace' );

gutenberg_override_style(
$styles,
'wp-reusable-blocks',
gutenberg_url( 'build/reusable-blocks/style.css' ),
array( 'wp-components' ),
filemtime( gutenberg_dir_path() . 'build/reusable-blocks/style.css' )
);
$styles->add_data( 'wp-reusable-block', 'rtl', 'replace' );
}
add_action( 'wp_default_styles', 'gutenberg_register_packages_styles' );

Expand Down
3 changes: 3 additions & 0 deletions packages/base-styles/_z-index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,9 @@ $z-layers: (
// #adminmenuwrap { z-index: 9990 }
".components-popover": 1000000,

// Should be above the popover (dropdown)
".reusable-blocks-menu-items__convert-modal": 1000001,

// ...Except for popovers immediately beneath wp-admin menu on large breakpoints
".components-popover.block-editor-inserter__popover": 99999,
".components-popover.table-of-contents__popover": 99998,
Expand Down
58 changes: 16 additions & 42 deletions packages/e2e-tests/specs/editor/various/reusable-blocks.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import {
} from '@wordpress/e2e-test-utils';

const reusableBlockNameInputSelector =
'.reusable-blocks-menu-items__convert-modal .components-text-control__input';
const reusableBlockInspectorNameInputSelector =
'.block-editor-block-inspector .components-text-control__input';

const saveAll = async () => {
Expand Down Expand Up @@ -49,6 +51,12 @@ const createReusableBlock = async ( content, title ) => {

await clickBlockToolbarButton( 'Options' );
await clickMenuItem( 'Add to Reusable blocks' );
const nameInput = await page.waitForSelector(
reusableBlockNameInputSelector
);
await nameInput.click();
await page.keyboard.type( title );
await page.keyboard.press( 'Enter' );

// Wait for creation to finish
await page.waitForXPath(
Expand All @@ -60,20 +68,6 @@ const createReusableBlock = async ( content, title ) => {
'.block-editor-block-list__block[data-type="core/block"]'
);
expect( block ).not.toBeNull();

await openDocumentSettingsSidebar();
const nameInput = await page.waitForSelector(
reusableBlockNameInputSelector
);
if ( title ) {
await nameInput.click();

// Select all of the text in the title field.
await pressKeyWithModifier( 'primary', 'a' );

// Give the reusable block a title
await page.keyboard.type( title );
}
};

describe( 'Reusable blocks', () => {
Expand All @@ -85,19 +79,8 @@ describe( 'Reusable blocks', () => {
await createNewPost();
} );

it( 'can be created with no title', async () => {
await createReusableBlock( 'Hello there!' );
await openDocumentSettingsSidebar();
const title = await page.$eval(
reusableBlockNameInputSelector,
( element ) => element.value
);
expect( title ).toBe( 'Untitled Reusable Block' );
} );

it( 'can be created, inserted, edited and converted to a regular block.', async () => {
await createReusableBlock( 'Hello there!', 'Greeting block' );
await saveAll();
await clearAllBlocks();

// Insert the reusable block we created above
Expand All @@ -106,7 +89,7 @@ describe( 'Reusable blocks', () => {
// Change the block's title
await openDocumentSettingsSidebar();
const nameInput = await page.waitForSelector(
reusableBlockNameInputSelector
reusableBlockInspectorNameInputSelector
);
await nameInput.click();
await pressKeyWithModifier( 'primary', 'a' );
Expand Down Expand Up @@ -157,9 +140,6 @@ describe( 'Reusable blocks', () => {
it( 'can be inserted after refresh', async () => {
await createReusableBlock( 'Awesome Paragraph', 'Awesome block' );

// Save the reusable block
await saveAll();

// Step 2. Create new post.
await createNewPost();

Expand All @@ -169,7 +149,7 @@ describe( 'Reusable blocks', () => {
// Check the title.
await openDocumentSettingsSidebar();
const title = await page.$eval(
reusableBlockNameInputSelector,
reusableBlockInspectorNameInputSelector,
( element ) => element.value
);
expect( title ).toBe( 'Awesome block' );
Expand All @@ -192,22 +172,18 @@ describe( 'Reusable blocks', () => {
await clickBlockToolbarButton( 'Options' );
await clickMenuItem( 'Add to Reusable blocks' );

// Wait for creation to finish
await page.waitForXPath(
'//*[contains(@class, "components-snackbar")]/*[text()="Block created."]'
);

// Set title.
await openDocumentSettingsSidebar();
// Set title
const nameInput = await page.waitForSelector(
reusableBlockNameInputSelector
);
await nameInput.click();
await pressKeyWithModifier( 'primary', 'a' );
await page.keyboard.type( 'Multi-selection reusable block' );
await page.keyboard.press( 'Enter' );

// Save the reusable block
await saveAll();
// Wait for creation to finish
await page.waitForXPath(
'//*[contains(@class, "components-snackbar")]/*[text()="Block created."]'
);

await clearAllBlocks();

Expand All @@ -226,7 +202,6 @@ describe( 'Reusable blocks', () => {
'Awesome Paragraph',
'Random reusable block'
);
await saveAll();
await clearAllBlocks();
await insertReusableBlock( 'Random reusable block' );

Expand Down Expand Up @@ -293,7 +268,6 @@ describe( 'Reusable blocks', () => {
'Awesome Paragraph',
'Duplicated reusable block'
);
await saveAll();
await clearAllBlocks();
await insertReusableBlock( 'Duplicated reusable block' );
await insertReusableBlock( 'Duplicated reusable block' );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,15 @@
*/
import { hasBlockSupport, isReusableBlock } from '@wordpress/blocks';
import { BlockSettingsMenuControls } from '@wordpress/block-editor';
import { useCallback } from '@wordpress/element';
import { MenuItem } from '@wordpress/components';
import { useCallback, useState } from '@wordpress/element';
import {
MenuItem,
Modal,
Button,
TextControl,
Flex,
FlexItem,
} from '@wordpress/components';
import { reusableBlock } from '@wordpress/icons';
import { useDispatch, useSelect } from '@wordpress/data';
import { __ } from '@wordpress/i18n';
Expand All @@ -27,6 +34,8 @@ export default function ReusableBlockConvertButton( {
clientIds,
rootClientId,
} ) {
const [ isModalOpen, setIsModalOpen ] = useState( false );
const [ title, setTitle ] = useState( '' );
const canConvert = useSelect(
( select ) => {
const { canUser } = select( 'core' );
Expand Down Expand Up @@ -76,9 +85,9 @@ export default function ReusableBlockConvertButton( {
noticesStore
);
const onConvert = useCallback(
async function () {
async function ( reusableBlockTitle ) {
try {
await convertBlocksToReusable( clientIds );
await convertBlocksToReusable( clientIds, reusableBlockTitle );
createSuccessNotice( __( 'Block created.' ), {
type: 'snackbar',
} );
Expand All @@ -98,15 +107,61 @@ export default function ReusableBlockConvertButton( {
return (
<BlockSettingsMenuControls>
{ ( { onClose } ) => (
<MenuItem
icon={ reusableBlock }
onClick={ () => {
onConvert();
onClose();
} }
>
{ __( 'Add to Reusable blocks' ) }
</MenuItem>
<>
<MenuItem
icon={ reusableBlock }
onClick={ () => {
setIsModalOpen( true );
} }
>
{ __( 'Add to Reusable blocks' ) }
</MenuItem>
{ isModalOpen && (
<Modal
title={ __( 'Create reusable block' ) }
closeLabel={ __( 'Close' ) }
onRequestClose={ () => {
setIsModalOpen( false );
setTitle( '' );
} }
overlayClassName="reusable-blocks-menu-items__convert-modal"
>
<form
onSubmit={ ( event ) => {
event.preventDefault();
onConvert( title );
setIsModalOpen( false );
setTitle( '' );
onClose();
} }
>
<TextControl
label={ __( 'Name your reusable block' ) }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be just "Add name" or "Name"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, I just used what was shown on the issue's video :)

value={ title }
onChange={ setTitle }
/>
<Flex justify="flex-end">
<FlexItem>
<Button
isSecondary
onClick={ () => {
setIsModalOpen( false );
setTitle( '' );
} }
>
{ __( 'Cancel' ) }
</Button>
</FlexItem>
<FlexItem>
<Button isPrimary type="submit">
{ __( 'Save' ) }
</Button>
</FlexItem>
</Flex>
</form>
</Modal>
) }
</>
) }
</BlockSettingsMenuControls>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.reusable-blocks-menu-items__convert-modal {
z-index: z-index(".reusable-blocks-menu-items__convert-modal");
}
5 changes: 3 additions & 2 deletions packages/reusable-blocks/src/store/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,10 @@ export function* __experimentalConvertBlockToStatic( clientId ) {
* Returns a generator converting one or more static blocks into a reusable block.
*
* @param {string[]} clientIds The client IDs of the block to detach.
* @param {string} title Reusable block title.
*/
export function* __experimentalConvertBlocksToReusable( clientIds ) {
yield convertBlocksToReusable( clientIds );
export function* __experimentalConvertBlocksToReusable( clientIds, title ) {
yield convertBlocksToReusable( clientIds, title );
}

/**
Expand Down
10 changes: 6 additions & 4 deletions packages/reusable-blocks/src/store/controls.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,15 @@ export function convertBlockToStatic( clientId ) {
/**
* Convert a static block to a reusable block effect handler
*
* @param {Array} clientIds Block IDs.
* @param {Array} clientIds Block IDs.
* @param {string} title Reusable block title.
* @return {Object} control descriptor.
*/
export function convertBlocksToReusable( clientIds ) {
export function convertBlocksToReusable( clientIds, title ) {
return {
type: 'CONVERT_BLOCKS_TO_REUSABLE',
clientIds,
title,
};
}

Expand Down Expand Up @@ -77,9 +79,9 @@ const controls = {

CONVERT_BLOCKS_TO_REUSABLE: createRegistryControl(
( registry ) =>
async function ( { clientIds } ) {
async function ( { clientIds, title } ) {
const reusableBlock = {
title: __( 'Untitled Reusable Block' ),
title: title || __( 'Untitled Reusable Block' ),
content: serialize(
registry
.select( 'core/block-editor' )
Expand Down
1 change: 1 addition & 0 deletions packages/reusable-blocks/src/style.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@import "./components/reusable-blocks-menu-items/style.scss"