From 931048218b552f8561cbca9719f7fcf6b0a8315e Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Thu, 24 Dec 2020 15:00:19 +0100 Subject: [PATCH 1/5] Use a controlled inner blocks for reusable blocks --- .../src/block/edit-panel/editor.scss | 46 ------ .../src/block/edit-panel/index.js | 108 +------------- packages/block-library/src/block/edit.js | 137 ++++++------------ 3 files changed, 49 insertions(+), 242 deletions(-) diff --git a/packages/block-library/src/block/edit-panel/editor.scss b/packages/block-library/src/block/edit-panel/editor.scss index 702f72e4dbace..1c07363c94557 100644 --- a/packages/block-library/src/block/edit-panel/editor.scss +++ b/packages/block-library/src/block/edit-panel/editor.scss @@ -11,50 +11,4 @@ background-color: $white; box-shadow: 0 0 0 $border-width $gray-900; outline: 1px solid transparent; // Shown for Windows 10 High Contrast mode. - - .reusable-block-edit-panel__info { - margin-right: auto; - } - - .reusable-block-edit-panel__label { - margin-right: $grid-unit-10; - white-space: nowrap; - font-family: $default-font; - font-size: $default-font-size; - } - - .reusable-block-edit-panel__title { - flex: 1 1 100%; - } - - .components-button.reusable-block-edit-panel__button { - // Prevent button shrinking in IE11 when other items have a 100% flex basis. - // This should be safe to apply in all browsers because we don't want these - // buttons to shrink anyway. - flex-shrink: 0; - } - - @include break-large() { - flex-wrap: nowrap; - - .reusable-block-edit-panel__title { - margin: 0; - } - - .components-button.reusable-block-edit-panel__button { - margin: 0 0 0 $grid-unit-10; - } - } -} - -.reusable-block-edit-panel__title[type="text"] { - @include input-control; -} - -.is-navigate-mode .is-selected .reusable-block-edit-panel { - box-shadow: 0 0 0 $border-width var(--wp-admin-theme-color); - - .is-dark-theme & { - box-shadow: 0 0 0 $border-width var(--wp-admin-theme-color); - } } diff --git a/packages/block-library/src/block/edit-panel/index.js b/packages/block-library/src/block/edit-panel/index.js index c3b60a963cf3e..eacea845fe3fb 100644 --- a/packages/block-library/src/block/edit-panel/index.js +++ b/packages/block-library/src/block/edit-panel/index.js @@ -1,9 +1,7 @@ /** * WordPress dependencies */ -import { Button } from '@wordpress/components'; -import { useInstanceId, usePrevious } from '@wordpress/compose'; -import { useEffect, useRef } from '@wordpress/element'; +import { TextControl } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; /** @typedef {import('@wordpress/element').WPComponent} WPComponent */ @@ -13,21 +11,9 @@ import { __ } from '@wordpress/i18n'; * * @typedef WPReusableBlockEditPanelProps * - * @property {boolean} isEditDisabled Is editing the reusable - * block disabled. - * @property {boolean} isEditing Is the reusable block - * being edited. - * @property {boolean} isSaving Is the reusable block - * being saved. - * @property {()=>void} onCancel Callback to run when - * editing is canceled. * @property {(newTitle:string)=>void} onChangeTitle Callback to run when the * title input value is * changed. - * @property {()=>void} onEdit Callback to run when - * editing begins. - * @property {()=>void} onSave Callback to run when - * saving. * @property {string} title Title of the reusable * block. */ @@ -39,91 +25,13 @@ import { __ } from '@wordpress/i18n'; * * @return {WPComponent} The panel. */ -export default function ReusableBlockEditPanel( { - isEditDisabled, - isEditing, - isSaving, - onChangeTitle, - onEdit, - onSave, - title, -} ) { - const instanceId = useInstanceId( ReusableBlockEditPanel ); - const titleField = useRef(); - const editButton = useRef(); - const wasEditing = usePrevious( isEditing ); - const wasSaving = usePrevious( isSaving ); - - // Select the title input when the form opens. - useEffect( () => { - if ( ! wasEditing && isEditing ) { - titleField.current.select(); - } - }, [ isEditing ] ); - - // Move focus back to the Edit button after pressing the Escape key or Save. - useEffect( () => { - if ( ( wasEditing || wasSaving ) && ! isEditing && ! isSaving ) { - editButton.current.focus(); - } - }, [ isEditing, isSaving ] ); - - function handleFormSubmit( event ) { - event.preventDefault(); - onSave(); - } - - function handleTitleChange( event ) { - onChangeTitle( event.target.value ); - } - +export default function ReusableBlockEditPanel( { onChange, title } ) { return ( - <> - { ! isEditing && ! isSaving && ( -
- { title } - -
- ) } - { ( isEditing || isSaving ) && ( -
- - - -
- ) } - + ); } diff --git a/packages/block-library/src/block/edit.js b/packages/block-library/src/block/edit.js index 1c7b9b039252c..4d261817c1330 100644 --- a/packages/block-library/src/block/edit.js +++ b/packages/block-library/src/block/edit.js @@ -2,24 +2,25 @@ * WordPress dependencies */ import { useSelect, useDispatch } from '@wordpress/data'; -import { useEntityBlockEditor } from '@wordpress/core-data'; -import { useCallback } from '@wordpress/element'; +import { + useEntityBlockEditor, + useEntityProp, + store as coreStore, +} from '@wordpress/core-data'; import { Placeholder, Spinner, - Disabled, ToolbarGroup, ToolbarButton, } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; import { - BlockEditorProvider, - WritingFlow, - BlockList, + __experimentalUseInnerBlocksProps as useInnerBlocksProps, + InnerBlocks, BlockControls, useBlockProps, + store as blockEditorStore, } from '@wordpress/block-editor'; -import { store as noticesStore } from '@wordpress/notices'; import { store as reusableBlocksStore } from '@wordpress/reusable-blocks'; /** @@ -34,69 +35,49 @@ export default function ReusableBlockEdit( { } ) { const recordArgs = [ 'postType', 'wp_block', ref ]; - const { - reusableBlock, - hasResolved, - isEditing, - isSaving, - canUserUpdate, - settings, - } = useSelect( + const { reusableBlock, hasResolved, hasInnerBlockSelected } = useSelect( ( select ) => ( { - reusableBlock: select( 'core' ).getEditedEntityRecord( + reusableBlock: select( coreStore ).getEditedEntityRecord( ...recordArgs ), - hasResolved: select( 'core' ).hasFinishedResolution( + hasResolved: select( coreStore ).hasFinishedResolution( 'getEditedEntityRecord', recordArgs ), - isSaving: select( 'core' ).isSavingEntityRecord( ...recordArgs ), - canUserUpdate: select( 'core' ).canUser( 'update', 'blocks', ref ), - isEditing: select( - reusableBlocksStore - ).__experimentalIsEditingReusableBlock( clientId ), - settings: select( 'core/block-editor' ).getSettings(), + hasInnerBlockSelected: select( + blockEditorStore + ).hasSelectedInnerBlock( clientId, true ), } ), [ ref, clientId ] ); - const { clearSelectedBlock } = useDispatch( 'core/block-editor' ); - const { editEntityRecord, saveEditedEntityRecord } = useDispatch( 'core' ); - const { __experimentalSetEditingReusableBlock } = useDispatch( - reusableBlocksStore - ); - const setIsEditing = useCallback( - ( value ) => { - __experimentalSetEditingReusableBlock( clientId, value ); - }, - [ clientId ] - ); - const { __experimentalConvertBlockToStatic: convertBlockToStatic, } = useDispatch( reusableBlocksStore ); - const { createSuccessNotice, createErrorNotice } = useDispatch( - noticesStore - ); - const save = useCallback( async function () { - try { - await saveEditedEntityRecord( ...recordArgs ); - createSuccessNotice( __( 'Block updated.' ), { - type: 'snackbar', - } ); - } catch ( error ) { - createErrorNotice( error.message, { - type: 'snackbar', - } ); - } - }, recordArgs ); - const [ blocks, onInput, onChange ] = useEntityBlockEditor( 'postType', 'wp_block', { id: ref } ); + const [ title, setTitle ] = useEntityProp( + 'postType', + 'wp_block', + 'title', + ref + ); + + const innerBlocksProps = useInnerBlocksProps( + {}, + { + value: blocks, + onInput, + onChange, + renderAppender: blocks?.length + ? undefined + : InnerBlocks.ButtonBlockAppender, + } + ); const blockProps = useBlockProps(); @@ -120,34 +101,6 @@ export default function ReusableBlockEdit( { ); } - /** - * Clear the selected block when focus moves to the reusable block list. - * These blocks are in different stores and only one block should be - * selected at a time. - */ - function onFocus() { - clearSelectedBlock(); - } - - let element = ( - -
- - - -
-
- ); - - if ( ! isEditing ) { - element = { element }; - } - return (
@@ -161,23 +114,15 @@ export default function ReusableBlockEdit( {
- { ( isSelected || isEditing ) && ( - setIsEditing( true ) } - onChangeTitle={ ( title ) => - editEntityRecord( ...recordArgs, { title } ) - } - onSave={ () => { - save(); - setIsEditing( false ); - } } - /> - ) } - { element } + { isSelected || + ( hasInnerBlockSelected && ( + + ) ) } + + {
}
); From 1f00883c1a906e6cd1041a44ad15daeb90ee9042 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Tue, 29 Dec 2020 16:56:37 +0100 Subject: [PATCH 2/5] Fix reusable blocks test --- packages/block-library/src/block/edit.js | 13 +- packages/e2e-test-utils/src/inserter.js | 12 +- .../reusable-blocks.test.js.snap | 2 +- .../editor/various/reusable-blocks.test.js | 288 +++++++----------- 4 files changed, 122 insertions(+), 193 deletions(-) diff --git a/packages/block-library/src/block/edit.js b/packages/block-library/src/block/edit.js index 4d261817c1330..42c88d9a263b3 100644 --- a/packages/block-library/src/block/edit.js +++ b/packages/block-library/src/block/edit.js @@ -114,13 +114,12 @@ export default function ReusableBlockEdit( {
- { isSelected || - ( hasInnerBlockSelected && ( - - ) ) } + { ( isSelected || hasInnerBlockSelected ) && ( + + ) } {
}
diff --git a/packages/e2e-test-utils/src/inserter.js b/packages/e2e-test-utils/src/inserter.js index c3d31299f3e42..800148d2c39e1 100644 --- a/packages/e2e-test-utils/src/inserter.js +++ b/packages/e2e-test-utils/src/inserter.js @@ -131,9 +131,9 @@ export async function searchForReusableBlock( searchTerm ) { */ export async function insertBlock( searchTerm ) { await searchForBlock( searchTerm ); - const insertButton = ( - await page.$x( `//button//span[contains(text(), '${ searchTerm }')]` ) - )[ 0 ]; + const insertButton = await page.waitForXPath( + `//button//span[contains(text(), '${ searchTerm }')]` + ); await insertButton.click(); // We should wait until the inserter closes and the focus moves to the content. await waitForInserterCloseAndContentFocus(); @@ -164,9 +164,9 @@ export async function insertPattern( searchTerm ) { */ export async function insertReusableBlock( searchTerm ) { await searchForReusableBlock( searchTerm ); - const insertButton = ( - await page.$x( `//button//span[contains(text(), '${ searchTerm }')]` ) - )[ 0 ]; + const insertButton = await page.waitForXPath( + `//button//span[contains(text(), '${ searchTerm }')]` + ); await insertButton.click(); // We should wait until the inserter closes and the focus moves to the content. await waitForInserterCloseAndContentFocus(); diff --git a/packages/e2e-tests/specs/editor/various/__snapshots__/reusable-blocks.test.js.snap b/packages/e2e-tests/specs/editor/various/__snapshots__/reusable-blocks.test.js.snap index a266c0df25c18..a0df67f902d1f 100644 --- a/packages/e2e-tests/specs/editor/various/__snapshots__/reusable-blocks.test.js.snap +++ b/packages/e2e-tests/specs/editor/various/__snapshots__/reusable-blocks.test.js.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Reusable blocks multi-selection reusable block can be converted back to regular blocks 1`] = ` +exports[`Reusable blocks can be created from multiselection and converted back to regular blocks 1`] = ` "

Hello there!

diff --git a/packages/e2e-tests/specs/editor/various/reusable-blocks.test.js b/packages/e2e-tests/specs/editor/various/reusable-blocks.test.js index 0d7c6d8baf236..23b612177302a 100644 --- a/packages/e2e-tests/specs/editor/various/reusable-blocks.test.js +++ b/packages/e2e-tests/specs/editor/various/reusable-blocks.test.js @@ -14,119 +14,104 @@ import { toggleGlobalBlockInserter, } from '@wordpress/e2e-test-utils'; -describe( 'Reusable blocks', () => { - beforeAll( async () => { - await createNewPost(); - } ); - - afterAll( async () => { - await trashAllPosts( 'wp_block' ); +const saveAll = async () => { + await page.click( '.editor-post-publish-button__button.has-changes-dot' ); + await page.waitForSelector( + 'button.editor-entities-saved-states__save-button' + ); + await page.click( 'button.editor-entities-saved-states__save-button' ); + + // no need to publish the post. + const cancelPublish = await page.waitForSelector( + '.editor-post-publish-panel__header-cancel-button button' + ); + await cancelPublish.click(); +}; + +const clearAllBlocks = async () => { + // Remove all blocks from the post so that we're working with a clean slate + await page.evaluate( () => { + const blocks = wp.data.select( 'core/block-editor' ).getBlocks(); + const clientIds = blocks.map( ( block ) => block.clientId ); + wp.data.dispatch( 'core/block-editor' ).removeBlocks( clientIds ); } ); +}; - beforeEach( async () => { - // Remove all blocks from the post so that we're working with a clean slate - await page.evaluate( () => { - const blocks = wp.data.select( 'core/block-editor' ).getBlocks(); - const clientIds = blocks.map( ( block ) => block.clientId ); - wp.data.dispatch( 'core/block-editor' ).removeBlocks( clientIds ); - } ); - } ); +const createReusableBlock = async ( content, title ) => { + // Insert a paragraph block + await insertBlock( 'Paragraph' ); + await page.keyboard.type( content ); - it( 'can be created', async () => { - // Insert a paragraph block - await insertBlock( 'Paragraph' ); - await page.keyboard.type( 'Hello there!' ); + await clickBlockToolbarButton( 'More options' ); + await clickMenuItem( 'Add to Reusable blocks' ); - await clickBlockToolbarButton( 'More options' ); - await clickMenuItem( 'Add to Reusable blocks' ); + // Wait for creation to finish + await page.waitForXPath( + '//*[contains(@class, "components-snackbar")]/*[text()="Block created."]' + ); - // Wait for creation to finish - await page.waitForXPath( - '//*[contains(@class, "components-snackbar")]/*[text()="Block created."]' - ); - await page.waitForXPath( - '//*[@class="block-library-block__reusable-block-container"]' + if ( title ) { + const nameInput = await page.waitForSelector( + '.block-library-block__reusable-block-container .components-text-control__input' ); + 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( 'Greeting block' ); + await page.keyboard.type( title ); + } - // Save the reusable block - const [ saveButton ] = await page.$x( '//button[text()="Save"]' ); - await saveButton.click(); + // Check that we have a reusable block on the page + const block = await page.waitForSelector( + '.block-editor-block-list__block[data-type="core/block"]' + ); + expect( block ).not.toBeNull(); +}; - // Wait for saving to finish - await page.waitForXPath( '//button[text()="Edit"]' ); +describe( 'Reusable blocks', () => { + beforeAll( async () => { + await createNewPost(); + } ); - // Check that we have a reusable block on the page - const block = await page.$( - '.block-editor-block-list__block[data-type="core/block"]' - ); - expect( block ).not.toBeNull(); + afterAll( async () => { + await trashAllPosts( 'wp_block' ); + } ); - // Check that its title is displayed - const title = await page.$eval( - '.reusable-block-edit-panel__info', - ( element ) => element.innerText - ); - expect( title ).toBe( 'Greeting block' ); + beforeEach( async () => { + await clearAllBlocks(); } ); it( 'can be created with no title', async () => { - // Insert a paragraph block - await insertBlock( 'Paragraph' ); - await page.keyboard.type( 'Hello there!' ); - - await clickBlockToolbarButton( 'More options' ); - await clickMenuItem( 'Add to Reusable blocks' ); - - // Wait for creation to finish - await page.waitForXPath( - '//*[contains(@class, "components-snackbar")]/*[text()="Block created."]' - ); - await page.waitForXPath( - '//*[@class="block-library-block__reusable-block-container"]' - ); - - // Save the reusable block - const [ saveButton ] = await page.$x( '//button[text()="Save"]' ); - await saveButton.click(); - - // Wait for saving to finish - await page.waitForXPath( '//button[text()="Edit"]' ); - - // Check that we have a reusable block on the page - const block = await page.$( - '.block-editor-block-list__block[data-type="core/block"]' + await createReusableBlock( 'Hello there!' ); + await page.waitForSelector( + '.block-library-block__reusable-block-container .components-text-control__input' ); - expect( block ).not.toBeNull(); - - // Check that it is untitled const title = await page.$eval( - '.reusable-block-edit-panel__info', - ( element ) => element.innerText + '.block-library-block__reusable-block-container .components-text-control__input', + ( element ) => element.value ); expect( title ).toBe( 'Untitled Reusable Block' ); } ); - it( 'can be inserted and edited', async () => { + 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 await insertReusableBlock( 'Greeting block' ); - // Put the reusable block in edit mode - const editButton = await page.waitForXPath( - '//button[text()="Edit" and not(@disabled)]' - ); - await editButton.click(); - // Change the block's title + const nameInput = await page.waitForSelector( + '.block-library-block__reusable-block-container .components-text-control__input' + ); + await nameInput.click(); + await pressKeyWithModifier( 'primary', 'a' ); await page.keyboard.type( 'Surprised greeting block' ); - // Tab three times to navigate to the block's content - await page.keyboard.press( 'Tab' ); + // Tab to navigate to the block's content await page.keyboard.press( 'Tab' ); // Quickly focus the paragraph block @@ -137,24 +122,7 @@ describe( 'Reusable blocks', () => { await page.keyboard.type( 'Oh! ' ); // Save the reusable block - const [ saveButton ] = await page.$x( '//button[text()="Save"]' ); - await saveButton.click(); - - // Wait for saving to finish - await page.waitForXPath( '//button[text()="Edit"]' ); - - // Check that we have a reusable block on the page - const block = await page.$( - '.block-editor-block-list__block[data-type="core/block"]' - ); - expect( block ).not.toBeNull(); - - // Check that its title is displayed - const title = await page.$eval( - '.reusable-block-edit-panel__info', - ( element ) => element.innerText - ); - expect( title ).toBe( 'Surprised greeting block' ); + await saveAll(); // Check that its content is up to date const text = await page.$eval( @@ -162,79 +130,53 @@ describe( 'Reusable blocks', () => { ( element ) => element.innerText ); expect( text ).toMatch( 'Oh! Hello there!' ); - } ); - it( 'can be inserted after refresh', async () => { - // Step 1. Insert a paragraph block + await clearAllBlocks(); - await insertBlock( 'Paragraph' ); - await page.keyboard.type( 'Awesome Paragraph' ); + // Insert the reusable block we edited above + await insertReusableBlock( 'Surprised greeting block' ); - await clickBlockToolbarButton( 'More options' ); - await clickMenuItem( 'Add to Reusable blocks' ); + // Convert block to a regular block + await clickBlockToolbarButton( 'Convert to regular blocks', 'content' ); - // Wait for creation to finish - await page.waitForXPath( - '//*[contains(@class, "components-snackbar")]/*[text()="Block created."]' - ); - await page.waitForXPath( - '//*[@class="block-library-block__reusable-block-container"]' + // Check that we have a paragraph block on the page + const paragraphBlock = await page.$( + '.block-editor-block-list__block[data-type="core/paragraph"]' ); + expect( paragraphBlock ).not.toBeNull(); - // Select all of the text in the title field. - await pressKeyWithModifier( 'primary', 'a' ); + // Check that its content is up to date + const paragraphContent = await page.$eval( + '.block-editor-block-list__block[data-type="core/paragraph"]', + ( element ) => element.innerText + ); + expect( paragraphContent ).toMatch( 'Oh! Hello there!' ); + } ); - // Give the reusable block a title - await page.keyboard.type( 'Awesome block' ); + it( 'can be inserted after refresh', async () => { + await createReusableBlock( 'Awesome Paragraph', 'Awesome block' ); // Save the reusable block - const [ saveButton ] = await page.$x( '//button[text()="Save"]' ); - await saveButton.click(); + await saveAll(); // Step 2. Create new post. - await createNewPost(); // Step 3. Insert the block created in Step 1. - await insertReusableBlock( 'Awesome block' ); - // Check that we have a reusable block on the page - const block = await page.$( - '.block-editor-block-list__block[data-type="core/block"]' + // Check the title. + await page.waitForSelector( + '.block-library-block__reusable-block-container .components-text-control__input' ); - expect( block ).not.toBeNull(); - - // Check that its title is displayed const title = await page.$eval( - '.reusable-block-edit-panel__info', - ( element ) => element.innerText + '.block-library-block__reusable-block-container .components-text-control__input', + ( element ) => element.value ); expect( title ).toBe( 'Awesome block' ); } ); - it( 'can be converted to a regular block', async () => { - // Insert the reusable block we edited above - await insertReusableBlock( 'Surprised greeting block' ); - - // Convert block to a regular block - await clickBlockToolbarButton( 'Convert to regular blocks', 'content' ); - - // Check that we have a paragraph block on the page - const block = await page.$( - '.block-editor-block-list__block[data-type="core/paragraph"]' - ); - expect( block ).not.toBeNull(); - - // Check that its content is up to date - const text = await page.$eval( - '.block-editor-block-list__block[data-type="core/paragraph"]', - ( element ) => element.innerText - ); - expect( text ).toMatch( 'Oh! Hello there!' ); - } ); - - it( 'can be created from multiselection', async () => { + it( 'can be created from multiselection and converted back to regular blocks', async () => { await createNewPost(); // Insert a Two paragraphs block @@ -255,38 +197,20 @@ describe( 'Reusable blocks', () => { await page.waitForXPath( '//*[contains(@class, "components-snackbar")]/*[text()="Block created."]' ); - await page.waitForXPath( - '//*[@class="block-library-block__reusable-block-container"]' - ); - // Select all of the text in the title field. + // Set title. + const nameInput = await page.waitForSelector( + '.block-library-block__reusable-block-container .components-text-control__input' + ); + await nameInput.click(); await pressKeyWithModifier( 'primary', 'a' ); - - // Give the reusable block a title await page.keyboard.type( 'Multi-selection reusable block' ); // Save the reusable block - const [ saveButton ] = await page.$x( '//button[text()="Save"]' ); - await saveButton.click(); + await saveAll(); - // Wait for saving to finish - await page.waitForXPath( '//button[text()="Edit"]' ); - - // Check that we have a reusable block on the page - const block = await page.$( - '.block-editor-block-list__block[data-type="core/block"]' - ); - expect( block ).not.toBeNull(); + await clearAllBlocks(); - // Check that its title is displayed - const title = await page.$eval( - '.reusable-block-edit-panel__info', - ( element ) => element.innerText - ); - expect( title ).toBe( 'Multi-selection reusable block' ); - } ); - - it( 'multi-selection reusable block can be converted back to regular blocks', async () => { // Insert the reusable block we edited above await insertReusableBlock( 'Multi-selection reusable block' ); @@ -298,12 +222,18 @@ describe( 'Reusable blocks', () => { } ); it( 'will not break the editor if empty', async () => { - await insertReusableBlock( 'Awesome block' ); + await createReusableBlock( + 'Awesome Paragraph', + 'Random reusable block' + ); + await saveAll(); + await clearAllBlocks(); + await insertReusableBlock( 'Random reusable block' ); await visitAdminPage( 'edit.php', [ 'post_type=wp_block' ] ); const [ editButton ] = await page.$x( - `//a[contains(@aria-label, 'Awesome block')]` + `//a[contains(@aria-label, 'Random reusable block')]` ); await editButton.click(); From 50830dda6657a6a45417c1f18e025c463aaf7b4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C3=ADas=20Ventura?= Date: Wed, 30 Dec 2020 10:47:03 +0100 Subject: [PATCH 3/5] Move title text control to the sidebar and remove from canvas. --- .../src/block/edit-panel/editor.scss | 14 ------- .../src/block/edit-panel/index.js | 37 ------------------- packages/block-library/src/block/edit.js | 29 ++++++--------- packages/block-library/src/editor.scss | 5 --- 4 files changed, 12 insertions(+), 73 deletions(-) delete mode 100644 packages/block-library/src/block/edit-panel/editor.scss delete mode 100644 packages/block-library/src/block/edit-panel/index.js diff --git a/packages/block-library/src/block/edit-panel/editor.scss b/packages/block-library/src/block/edit-panel/editor.scss deleted file mode 100644 index 1c07363c94557..0000000000000 --- a/packages/block-library/src/block/edit-panel/editor.scss +++ /dev/null @@ -1,14 +0,0 @@ -.block-editor-block-list__layout .reusable-block-edit-panel { - align-items: center; - display: flex; - flex-wrap: wrap; - font-family: $default-font; - font-size: $default-font-size; - padding: ($grid-unit-10 - $border-width - $border-width) $grid-unit-15; - - // Block UI appearance. - border-radius: $radius-block-ui; - background-color: $white; - box-shadow: 0 0 0 $border-width $gray-900; - outline: 1px solid transparent; // Shown for Windows 10 High Contrast mode. -} diff --git a/packages/block-library/src/block/edit-panel/index.js b/packages/block-library/src/block/edit-panel/index.js deleted file mode 100644 index eacea845fe3fb..0000000000000 --- a/packages/block-library/src/block/edit-panel/index.js +++ /dev/null @@ -1,37 +0,0 @@ -/** - * WordPress dependencies - */ -import { TextControl } from '@wordpress/components'; -import { __ } from '@wordpress/i18n'; - -/** @typedef {import('@wordpress/element').WPComponent} WPComponent */ - -/** - * ReusableBlockEditPanel props. - * - * @typedef WPReusableBlockEditPanelProps - * - * @property {(newTitle:string)=>void} onChangeTitle Callback to run when the - * title input value is - * changed. - * @property {string} title Title of the reusable - * block. - */ - -/** - * Panel for enabling the editing and saving of a reusable block. - * - * @param {WPReusableBlockEditPanelProps} props Component props. - * - * @return {WPComponent} The panel. - */ -export default function ReusableBlockEditPanel( { onChange, title } ) { - return ( - - ); -} diff --git a/packages/block-library/src/block/edit.js b/packages/block-library/src/block/edit.js index 42c88d9a263b3..28fc1a50f8124 100644 --- a/packages/block-library/src/block/edit.js +++ b/packages/block-library/src/block/edit.js @@ -12,30 +12,27 @@ import { Spinner, ToolbarGroup, ToolbarButton, + TextControl, + PanelBody, } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; import { __experimentalUseInnerBlocksProps as useInnerBlocksProps, InnerBlocks, BlockControls, + InspectorControls, useBlockProps, - store as blockEditorStore, } from '@wordpress/block-editor'; import { store as reusableBlocksStore } from '@wordpress/reusable-blocks'; /** * Internal dependencies */ -import ReusableBlockEditPanel from './edit-panel'; -export default function ReusableBlockEdit( { - attributes: { ref }, - clientId, - isSelected, -} ) { +export default function ReusableBlockEdit( { attributes: { ref }, clientId } ) { const recordArgs = [ 'postType', 'wp_block', ref ]; - const { reusableBlock, hasResolved, hasInnerBlockSelected } = useSelect( + const { reusableBlock, hasResolved } = useSelect( ( select ) => ( { reusableBlock: select( coreStore ).getEditedEntityRecord( ...recordArgs @@ -44,9 +41,6 @@ export default function ReusableBlockEdit( { 'getEditedEntityRecord', recordArgs ), - hasInnerBlockSelected: select( - blockEditorStore - ).hasSelectedInnerBlock( clientId, true ), } ), [ ref, clientId ] ); @@ -112,15 +106,16 @@ export default function ReusableBlockEdit( { - -
- { ( isSelected || hasInnerBlockSelected ) && ( - + + - ) } - + + +
{
}
diff --git a/packages/block-library/src/editor.scss b/packages/block-library/src/editor.scss index 0ece7da318dc6..c9aee9f8c1be7 100644 --- a/packages/block-library/src/editor.scss +++ b/packages/block-library/src/editor.scss @@ -52,11 +52,6 @@ @import "./query/editor.scss"; @import "./post-featured-image/editor.scss"; -/** - * Import styles from internal editor components used by the blocks. - */ -@import "./block/edit-panel/editor.scss"; - :root .editor-styles-wrapper { // Background colors. @include background-colors(); From d5cf25b2fe857f77bca59c6807f0ec40fe40a90d Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Wed, 30 Dec 2020 10:57:14 +0100 Subject: [PATCH 4/5] Fix reusable block name input --- packages/block-library/src/block/edit.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/block-library/src/block/edit.js b/packages/block-library/src/block/edit.js index 28fc1a50f8124..6e3f999ba3638 100644 --- a/packages/block-library/src/block/edit.js +++ b/packages/block-library/src/block/edit.js @@ -110,7 +110,7 @@ export default function ReusableBlockEdit( { attributes: { ref }, clientId } ) { From 47b98fc6f47283b4661d598d94b6bf4da23645a1 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Wed, 30 Dec 2020 11:52:46 +0100 Subject: [PATCH 5/5] Fix e2e tests after moving the name input --- .../editor/various/reusable-blocks.test.js | 47 ++++++++++--------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/packages/e2e-tests/specs/editor/various/reusable-blocks.test.js b/packages/e2e-tests/specs/editor/various/reusable-blocks.test.js index 23b612177302a..7c21e35505619 100644 --- a/packages/e2e-tests/specs/editor/various/reusable-blocks.test.js +++ b/packages/e2e-tests/specs/editor/various/reusable-blocks.test.js @@ -12,8 +12,12 @@ import { trashAllPosts, visitAdminPage, toggleGlobalBlockInserter, + openDocumentSettingsSidebar, } from '@wordpress/e2e-test-utils'; +const reusableBlockNameInputSelector = + '.block-editor-block-inspector .components-text-control__input'; + const saveAll = async () => { await page.click( '.editor-post-publish-button__button.has-changes-dot' ); await page.waitForSelector( @@ -50,10 +54,17 @@ const createReusableBlock = async ( content, title ) => { '//*[contains(@class, "components-snackbar")]/*[text()="Block created."]' ); + // Check that we have a reusable block on the page + const block = await page.waitForSelector( + '.block-editor-block-list__block[data-type="core/block"]' + ); + expect( block ).not.toBeNull(); + + await openDocumentSettingsSidebar(); + const nameInput = await page.waitForSelector( + reusableBlockNameInputSelector + ); if ( title ) { - const nameInput = await page.waitForSelector( - '.block-library-block__reusable-block-container .components-text-control__input' - ); await nameInput.click(); // Select all of the text in the title field. @@ -62,12 +73,6 @@ const createReusableBlock = async ( content, title ) => { // Give the reusable block a title await page.keyboard.type( title ); } - - // Check that we have a reusable block on the page - const block = await page.waitForSelector( - '.block-editor-block-list__block[data-type="core/block"]' - ); - expect( block ).not.toBeNull(); }; describe( 'Reusable blocks', () => { @@ -85,11 +90,9 @@ describe( 'Reusable blocks', () => { it( 'can be created with no title', async () => { await createReusableBlock( 'Hello there!' ); - await page.waitForSelector( - '.block-library-block__reusable-block-container .components-text-control__input' - ); + await openDocumentSettingsSidebar(); const title = await page.$eval( - '.block-library-block__reusable-block-container .components-text-control__input', + reusableBlockNameInputSelector, ( element ) => element.value ); expect( title ).toBe( 'Untitled Reusable Block' ); @@ -104,17 +107,18 @@ describe( 'Reusable blocks', () => { await insertReusableBlock( 'Greeting block' ); // Change the block's title + await openDocumentSettingsSidebar(); const nameInput = await page.waitForSelector( - '.block-library-block__reusable-block-container .components-text-control__input' + reusableBlockNameInputSelector ); await nameInput.click(); await pressKeyWithModifier( 'primary', 'a' ); await page.keyboard.type( 'Surprised greeting block' ); - // Tab to navigate to the block's content - await page.keyboard.press( 'Tab' ); - // Quickly focus the paragraph block + await page.click( + '.block-editor-block-list__block[data-type="core/block"] p' + ); await page.keyboard.press( 'Escape' ); // Enter navigation mode await page.keyboard.press( 'Enter' ); // Enter edit mode @@ -166,11 +170,9 @@ describe( 'Reusable blocks', () => { await insertReusableBlock( 'Awesome block' ); // Check the title. - await page.waitForSelector( - '.block-library-block__reusable-block-container .components-text-control__input' - ); + await openDocumentSettingsSidebar(); const title = await page.$eval( - '.block-library-block__reusable-block-container .components-text-control__input', + reusableBlockNameInputSelector, ( element ) => element.value ); expect( title ).toBe( 'Awesome block' ); @@ -199,8 +201,9 @@ describe( 'Reusable blocks', () => { ); // Set title. + await openDocumentSettingsSidebar(); const nameInput = await page.waitForSelector( - '.block-library-block__reusable-block-container .components-text-control__input' + reusableBlockNameInputSelector ); await nameInput.click(); await pressKeyWithModifier( 'primary', 'a' );